Enhanced ICU driver.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7211 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
gdisirio 2014-08-31 17:21:02 +00:00
parent 87e4b85755
commit 6c97d4f6fb
10 changed files with 50 additions and 32 deletions

View File

@ -183,7 +183,7 @@ typedef void (*icucallback_t)(ICUDriver *icup);
* @notapi * @notapi
*/ */
#define _icu_isr_invoke_width_cb(icup) do { \ #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->period_cb != NULL)) \
(icup)->config->width_cb(icup); \ (icup)->config->width_cb(icup); \
} while (0) } while (0)
@ -196,11 +196,10 @@ typedef void (*icucallback_t)(ICUDriver *icup);
* @notapi * @notapi
*/ */
#define _icu_isr_invoke_period_cb(icup) do { \ #define _icu_isr_invoke_period_cb(icup) do { \
icustate_t previous_state = (icup)->state; \ if (((icup)->state == ICU_ACTIVE) && \
(icup)->state = ICU_ACTIVE; \
if ((previous_state != ICU_WAITING) && \
((icup)->config->period_cb != NULL)) \ ((icup)->config->period_cb != NULL)) \
(icup)->config->period_cb(icup); \ (icup)->config->period_cb(icup); \
(icup)->state = ICU_ACTIVE; \
} while (0) } while (0)
/** /**

View File

@ -108,17 +108,18 @@ ICUDriver ICUD9;
* @param[in] icup pointer to the @p ICUDriver object * @param[in] icup pointer to the @p ICUDriver object
*/ */
static void icu_lld_serve_interrupt(ICUDriver *icup) { static void icu_lld_serve_interrupt(ICUDriver *icup) {
uint16_t sr; uint32_t sr;
sr = icup->tim->SR; sr = icup->tim->SR;
sr &= icup->tim->DIER & STM32_TIM_DIER_IRQ_MASK; sr &= icup->tim->DIER & STM32_TIM_DIER_IRQ_MASK;
icup->tim->SR = ~sr; icup->tim->SR = ~sr;
if (icup->config->channel == ICU_CHANNEL_1) { if (icup->config->channel == ICU_CHANNEL_1) {
if ((sr & STM32_TIM_SR_CC1IF) != 0)
_icu_isr_invoke_period_cb(icup);
if ((sr & STM32_TIM_SR_CC2IF) != 0) if ((sr & STM32_TIM_SR_CC2IF) != 0)
_icu_isr_invoke_width_cb(icup); _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) if ((sr & STM32_TIM_SR_CC1IF) != 0)
_icu_isr_invoke_width_cb(icup); _icu_isr_invoke_width_cb(icup);
if ((sr & STM32_TIM_SR_CC2IF) != 0) if ((sr & STM32_TIM_SR_CC2IF) != 0)
@ -506,7 +507,8 @@ void icu_lld_start(ICUDriver *icup) {
data faster from within callbacks.*/ data faster from within callbacks.*/
icup->wccrp = &icup->tim->CCR[1]; icup->wccrp = &icup->tim->CCR[1];
icup->pccrp = &icup->tim->CCR[0]; icup->pccrp = &icup->tim->CCR[0];
} else { }
else {
/* Selected input 2. /* Selected input 2.
CCMR1_CC1S = 10 = CH1 Input on TI2. CCMR1_CC1S = 10 = CH1 Input on TI2.
CCMR1_CC2S = 01 = CH2 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. * brings the driver in the @p ICU_ACTIVE state.
* @note If notifications are enabled then the transition to the * @note If notifications are enabled then the transition to the
* @p ICU_ACTIVE state is done automatically on the first edge. * @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 * @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) { 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. /* If interrupts were already enabled then the operation is skipped.
This is done in order to avoid clearing the SR and risk losing This is done in order to avoid clearing the SR and risk losing
pending interrupts.*/ 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.*/ /* Previously triggered IRQs are ignored, status cleared.*/
icup->tim->SR = 0; icup->tim->SR = 0;
@ -669,7 +680,8 @@ void icu_enable_notifications(ICUDriver *icup) {
/* Optionally enabling width callback on CC2.*/ /* Optionally enabling width callback on CC2.*/
if (icup->config->width_cb != NULL) if (icup->config->width_cb != NULL)
dier |= STM32_TIM_DIER_CC2IE; dier |= STM32_TIM_DIER_CC2IE;
} else { }
else {
/* Enabling periodic callback on CC2.*/ /* Enabling periodic callback on CC2.*/
dier |= STM32_TIM_DIER_CC2IE; dier |= STM32_TIM_DIER_CC2IE;

View File

@ -109,7 +109,7 @@ PWMDriver PWMD9;
* @param[in] pwmp pointer to a @p PWMDriver object * @param[in] pwmp pointer to a @p PWMDriver object
*/ */
static void pwm_lld_serve_interrupt(PWMDriver *pwmp) { static void pwm_lld_serve_interrupt(PWMDriver *pwmp) {
uint16_t sr; uint32_t sr;
sr = pwmp->tim->SR; sr = pwmp->tim->SR;
sr &= pwmp->tim->DIER & STM32_TIM_DIER_IRQ_MASK; sr &= pwmp->tim->DIER & STM32_TIM_DIER_IRQ_MASK;

View File

@ -48,13 +48,13 @@ icucnt_t last_width, last_period;
static void icuwidthcb(ICUDriver *icup) { static void icuwidthcb(ICUDriver *icup) {
palSetPad(GPIOC, GPIOC_LED3); palSetPad(GPIOC, GPIOC_LED3);
last_width = icuGetWidth(icup); last_width = icuGetWidthX(icup);
} }
static void icuperiodcb(ICUDriver *icup) { static void icuperiodcb(ICUDriver *icup) {
palClearPad(GPIOC, GPIOC_LED3); palClearPad(GPIOC, GPIOC_LED3);
last_period = icuGetPeriod(icup); last_period = icuGetPeriodX(icup);
} }
static void icuoverflowcb(ICUDriver *icup) { static void icuoverflowcb(ICUDriver *icup) {
@ -98,7 +98,8 @@ int main(void) {
palSetPadMode(GPIOA, 8, PAL_MODE_ALTERNATE(2)); palSetPadMode(GPIOA, 8, PAL_MODE_ALTERNATE(2));
icuStart(&ICUD3, &icucfg); icuStart(&ICUD3, &icucfg);
palSetPadMode(GPIOA, 6, PAL_MODE_ALTERNATE(1)); palSetPadMode(GPIOA, 6, PAL_MODE_ALTERNATE(1));
icuEnable(&ICUD3); icuStartCapture(&ICUD3);
icuEnableNotifications(&ICUD3);
chThdSleepMilliseconds(2000); chThdSleepMilliseconds(2000);
/* /*
@ -132,7 +133,7 @@ int main(void) {
*/ */
pwmDisableChannel(&PWMD1, 0); pwmDisableChannel(&PWMD1, 0);
pwmStop(&PWMD1); pwmStop(&PWMD1);
icuDisable(&ICUD3); icuStopCapture(&ICUD3);
icuStop(&ICUD3); icuStop(&ICUD3);
palClearPad(GPIOC, GPIOC_LED3); palClearPad(GPIOC, GPIOC_LED3);
palClearPad(GPIOC, GPIOC_LED4); palClearPad(GPIOC, GPIOC_LED4);

View File

@ -50,12 +50,12 @@ icucnt_t last_width, last_period;
static void icuwidthcb(ICUDriver *icup) { static void icuwidthcb(ICUDriver *icup) {
last_width = icuGetWidth(icup); last_width = icuGetWidthX(icup);
} }
static void icuperiodcb(ICUDriver *icup) { static void icuperiodcb(ICUDriver *icup) {
last_period = icuGetPeriod(icup); last_period = icuGetPeriodX(icup);
} }
static ICUConfig icucfg = { static ICUConfig icucfg = {
@ -95,7 +95,8 @@ int main(void) {
pwmEnablePeriodicNotification(&PWMD1); pwmEnablePeriodicNotification(&PWMD1);
palSetPadMode(IOPORT1, 8, PAL_MODE_STM32_ALTERNATE_PUSHPULL); palSetPadMode(IOPORT1, 8, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
icuStart(&ICUD4, &icucfg); icuStart(&ICUD4, &icucfg);
icuEnable(&ICUD4); icuStartCapture(&ICUD4);
icuEnableNotifications(&ICUD4);
chThdSleepMilliseconds(2000); chThdSleepMilliseconds(2000);
/* /*
@ -129,7 +130,7 @@ int main(void) {
*/ */
pwmDisableChannel(&PWMD1, 0); pwmDisableChannel(&PWMD1, 0);
pwmStop(&PWMD1); pwmStop(&PWMD1);
icuDisable(&ICUD4); icuStopCapture(&ICUD4);
icuStop(&ICUD4); icuStop(&ICUD4);
palSetPad(IOPORT3, GPIOC_LED); palSetPad(IOPORT3, GPIOC_LED);

View File

@ -94,6 +94,7 @@ int main(void) {
icuStart(&ICUD3, &icucfg); icuStart(&ICUD3, &icucfg);
palSetPadMode(GPIOC, 6, PAL_MODE_ALTERNATE(2)); palSetPadMode(GPIOC, 6, PAL_MODE_ALTERNATE(2));
icuStartCapture(&ICUD3); icuStartCapture(&ICUD3);
icuEnableNotifications(&ICUD3);
chThdSleepMilliseconds(2000); chThdSleepMilliseconds(2000);
/* /*

View File

@ -48,4 +48,5 @@
</scannerConfigBuildInfo> </scannerConfigBuildInfo>
</storageModule> </storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/> <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope"/>
</cproject> </cproject>

View File

@ -48,13 +48,13 @@ icucnt_t last_width, last_period;
static void icuwidthcb(ICUDriver *icup) { static void icuwidthcb(ICUDriver *icup) {
palSetPad(GPIOC, GPIOC_LED2); palSetPad(GPIOC, GPIOC_LED2);
last_width = icuGetWidth(icup); last_width = icuGetWidthX(icup);
} }
static void icuperiodcb(ICUDriver *icup) { static void icuperiodcb(ICUDriver *icup) {
palClearPad(GPIOC, GPIOC_LED2); palClearPad(GPIOC, GPIOC_LED2);
last_period = icuGetPeriod(icup); last_period = icuGetPeriodX(icup);
} }
static ICUConfig icucfg = { static ICUConfig icucfg = {
@ -93,7 +93,8 @@ int main(void) {
palSetPadMode(GPIOC, 0, PAL_MODE_ALTERNATE(2)); palSetPadMode(GPIOC, 0, PAL_MODE_ALTERNATE(2));
icuStart(&ICUD3, &icucfg); icuStart(&ICUD3, &icucfg);
palSetPadMode(GPIOC, 6, PAL_MODE_ALTERNATE(2)); palSetPadMode(GPIOC, 6, PAL_MODE_ALTERNATE(2));
icuEnable(&ICUD3); icuStartCapture(&ICUD3);
icuEnableNotifications(&ICUD3);
chThdSleepMilliseconds(2000); chThdSleepMilliseconds(2000);
/* /*
@ -127,7 +128,7 @@ int main(void) {
*/ */
pwmDisableChannel(&PWMD5, 0); pwmDisableChannel(&PWMD5, 0);
pwmStop(&PWMD5); pwmStop(&PWMD5);
icuDisable(&ICUD3); icuStopCapture(&ICUD3);
icuStop(&ICUD3); icuStop(&ICUD3);
/* /*

View File

@ -48,13 +48,13 @@ icucnt_t last_width, last_period;
static void icuwidthcb(ICUDriver *icup) { static void icuwidthcb(ICUDriver *icup) {
palSetPad(GPIOD, GPIOD_LED4); palSetPad(GPIOD, GPIOD_LED4);
last_width = icuGetWidth(icup); last_width = icuGetWidthX(icup);
} }
static void icuperiodcb(ICUDriver *icup) { static void icuperiodcb(ICUDriver *icup) {
palClearPad(GPIOD, GPIOD_LED4); palClearPad(GPIOD, GPIOD_LED4);
last_period = icuGetPeriod(icup); last_period = icuGetPeriodX(icup);
} }
static ICUConfig icucfg = { static ICUConfig icucfg = {
@ -93,7 +93,8 @@ int main(void) {
palSetPadMode(GPIOA, 8, PAL_MODE_ALTERNATE(1)); palSetPadMode(GPIOA, 8, PAL_MODE_ALTERNATE(1));
icuStart(&ICUD3, &icucfg); icuStart(&ICUD3, &icucfg);
palSetPadMode(GPIOC, 6, PAL_MODE_ALTERNATE(2)); palSetPadMode(GPIOC, 6, PAL_MODE_ALTERNATE(2));
icuEnable(&ICUD3); icuStartCapture(&ICUD3);
icuEnableNotifications(&ICUD3);
chThdSleepMilliseconds(2000); chThdSleepMilliseconds(2000);
/* /*
@ -127,7 +128,7 @@ int main(void) {
*/ */
pwmDisableChannel(&PWMD1, 0); pwmDisableChannel(&PWMD1, 0);
pwmStop(&PWMD1); pwmStop(&PWMD1);
icuDisable(&ICUD3); icuStopCapture(&ICUD3);
icuStop(&ICUD3); icuStop(&ICUD3);
palClearPad(GPIOD, GPIOD_LED4); palClearPad(GPIOD, GPIOD_LED4);
palClearPad(GPIOD, GPIOD_LED5); palClearPad(GPIOD, GPIOD_LED5);

View File

@ -48,13 +48,13 @@ icucnt_t last_width, last_period;
static void icuwidthcb(ICUDriver *icup) { static void icuwidthcb(ICUDriver *icup) {
palSetPad(GPIOB, GPIOB_LED3); palSetPad(GPIOB, GPIOB_LED3);
last_width = icuGetWidth(icup); last_width = icuGetWidthX(icup);
} }
static void icuperiodcb(ICUDriver *icup) { static void icuperiodcb(ICUDriver *icup) {
palClearPad(GPIOB, GPIOB_LED3); palClearPad(GPIOB, GPIOB_LED3);
last_period = icuGetPeriod(icup); last_period = icuGetPeriodX(icup);
} }
static ICUConfig icucfg = { static ICUConfig icucfg = {
@ -93,7 +93,8 @@ int main(void) {
palSetPadMode(GPIOA, 15, PAL_MODE_ALTERNATE(1)); palSetPadMode(GPIOA, 15, PAL_MODE_ALTERNATE(1));
icuStart(&ICUD3, &icucfg); icuStart(&ICUD3, &icucfg);
palSetPadMode(GPIOC, 6, PAL_MODE_ALTERNATE(2)); palSetPadMode(GPIOC, 6, PAL_MODE_ALTERNATE(2));
icuEnable(&ICUD3); icuStartCapture(&ICUD3);
icuEnableNotifications(&ICUD3);
chThdSleepMilliseconds(2000); chThdSleepMilliseconds(2000);
/* /*
@ -127,7 +128,7 @@ int main(void) {
*/ */
pwmDisableChannel(&PWMD2, 0); pwmDisableChannel(&PWMD2, 0);
pwmStop(&PWMD2); pwmStop(&PWMD2);
icuDisable(&ICUD3); icuStopCapture(&ICUD3);
icuStop(&ICUD3); icuStop(&ICUD3);
palClearPad(GPIOB, GPIOB_LED3); palClearPad(GPIOB, GPIOB_LED3);
palClearPad(GPIOB, GPIOB_LED4); palClearPad(GPIOB, GPIOB_LED4);