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:
parent
87e4b85755
commit
6c97d4f6fb
|
@ -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)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue