EICU. Fixed handlign of 32-bit timers. General code cleanup. PWM mode still untested.

This commit is contained in:
barthess 2015-03-01 21:09:12 +03:00
parent 8bb246b572
commit 4764c3ba15
4 changed files with 181 additions and 154 deletions

View File

@ -43,12 +43,12 @@
* @brief Driver state machine possible states. * @brief Driver state machine possible states.
*/ */
typedef enum { typedef enum {
EICU_UNINIT = 0, /* Not initialized. */ EICU_UNINIT = 0, /* Not initialized. */
EICU_STOP = 1, /* Stopped. */ EICU_STOP = 1, /* Stopped. */
EICU_READY = 2, /* Ready. */ EICU_READY = 2, /* Ready. */
EICU_WAITING = 3, /* Waiting for first edge. */ EICU_WAITING = 3, /* Waiting for first edge. */
EICU_ACTIVE = 4, /* Active cycle phase. */ EICU_ACTIVE = 4, /* Active cycle phase. */
EICU_IDLE = 5 /* Idle cycle phase. */ EICU_IDLE = 5 /* Idle cycle phase. */
} eicustate_t; } eicustate_t;
/** /**
@ -103,10 +103,10 @@ typedef void (*eicucallback_t)(EICUDriver *eicup, eicuchannel_t channel);
#define eicuDisableI(eicup) eicu_lld_disable(eicup) #define eicuDisableI(eicup) eicu_lld_disable(eicup)
/** /**
* @brief Returns the width of the latest pulse. * @brief Returns the time of the latest measurement.
* @details The pulse width is defined as number of ticks between the start * @details The pulse width is defined as number of ticks between the 2
* edge and the stop edge. * capture events depending on EICU mode (pulse width or period).
* @note This function is meant to be invoked from the width capture * @note This function is meant to be invoked from the capture
* callback only. * callback only.
* *
* @param[in] eicup Pointer to the @p EICUDriver object * @param[in] eicup Pointer to the @p EICUDriver object
@ -115,13 +115,13 @@ typedef void (*eicucallback_t)(EICUDriver *eicup, eicuchannel_t channel);
* *
* @special * @special
*/ */
#define eicuGetWidth(eicup, channel) eicu_lld_get_width((eicup), (channel)) #define eicuGetTime(eicup, channel) eicu_lld_get_time((eicup), (channel))
/** /**
* @brief Returns the width of the latest cycle. * @brief Returns the width of the latest cycle.
* @details The cycle width is defined as number of ticks between a start * @details The cycle width is defined as number of ticks between a start
* edge and the next start edge. * edge and the next start edge.
* @note This function is meant to be invoked from the width capture * @note This function is meant to be invoked from the capture
* callback only. * callback only.
* *
* @param[in] eicup Pointer to the @p EICUDriver object * @param[in] eicup Pointer to the @p EICUDriver object
@ -144,11 +144,12 @@ typedef void (*eicucallback_t)(EICUDriver *eicup, eicuchannel_t channel);
* *
* @notapi * @notapi
*/ */
#define _eicu_isr_invoke_pwm_width_cb(eicup, channel) { \ static inline void _eicu_isr_invoke_pwm_width_cb(EICUDriver *eicup,
if ((eicup)->state != EICU_WAITING) { \ eicuchannel_t channel) {
(eicup)->state = EICU_IDLE; \ if (eicup->state != EICU_WAITING) {
(eicup)->config->iccfgp[channel]->width_cb((eicup), (channel)); \ eicup->state = EICU_IDLE;
} \ eicup->config->iccfgp[channel]->capture_cb(eicup, channel);
}
} }
/** /**
@ -159,11 +160,12 @@ typedef void (*eicucallback_t)(EICUDriver *eicup, eicuchannel_t channel);
* *
* @notapi * @notapi
*/ */
#define _eicu_isr_invoke_pwm_period_cb(eicup, channel) { \ static inline void _eicu_isr_invoke_pwm_period_cb(EICUDriver *eicup,
eicustate_t previous_state = (eicup)->state; \ eicuchannel_t channel) {
(eicup)->state = EICU_ACTIVE; \ eicustate_t previous_state = eicup->state;
if (previous_state != EICU_WAITING) \ eicup->state = EICU_ACTIVE;
(eicup)->config->period_cb((eicup), (channel)); \ if (previous_state != EICU_WAITING)
eicup->config->period_cb(eicup, channel);
} }
/** /**
@ -178,16 +180,18 @@ typedef void (*eicucallback_t)(EICUDriver *eicup, eicuchannel_t channel);
* *
* @notapi * @notapi
*/ */
#define _eicu_isr_invoke_pulse_width_cb(eicup, channel) { \ static inline void _eicu_isr_invoke_pulse_width_cb(EICUDriver *eicup,
if ((eicup)->state == EICU_ACTIVE) { \ eicuchannel_t channel) {
(eicup)->state = EICU_READY; \ if (eicup->state == EICU_ACTIVE) {
eicu_lld_invert_polarity((eicup), (channel)); \ eicup->state = EICU_READY;
(eicup)->config->iccfgp[(channel)]->width_cb((eicup), (channel)); \ eicu_lld_invert_polarity(eicup, channel);
} else { \ eicup->config->iccfgp[channel]->capture_cb(eicup, channel);
(eicup)->state = EICU_ACTIVE; \ }
(eicup)->last_count[(channel)] = eicu_lld_get_compare((eicup), (channel)); \ else {
eicu_lld_invert_polarity((eicup), (channel)); \ eicup->state = EICU_ACTIVE;
} \ eicup->last_count[channel] = eicu_lld_get_compare(eicup, channel);
eicu_lld_invert_polarity(eicup, channel);
}
} }
/** /**
@ -198,9 +202,11 @@ typedef void (*eicucallback_t)(EICUDriver *eicup, eicuchannel_t channel);
* *
* @notapi * @notapi
*/ */
#define _eicu_isr_invoke_edge_detect_cb(eicup, channel) { \ static inline void _eicu_isr_invoke_edge_detect_cb(EICUDriver *eicup,
(eicup)->state = EICU_READY; \ eicuchannel_t channel) {
(eicup)->config->iccfgp[(channel)]->width_cb((eicup), (channel)); \ eicup->state = EICU_READY;
eicup->config->iccfgp[channel]->capture_cb(eicup, channel);
eicup->last_count[channel] = eicu_lld_get_compare(eicup, channel);
} }
/** /**

View File

@ -25,7 +25,6 @@
/* /*
* Hardware Abstraction Layer for Extended Input Capture Unit * Hardware Abstraction Layer for Extended Input Capture Unit
*/ */
#include "hal.h" #include "hal.h"
#if HAL_USE_EICU || defined(__DOXYGEN__) #if HAL_USE_EICU || defined(__DOXYGEN__)
@ -113,8 +112,7 @@ EICUDriver EICUD12;
* *
* @param[in] eicup Pointer to the @p EICUDriver object * @param[in] eicup Pointer to the @p EICUDriver object
*/ */
static void eicu_lld_serve_interrupt(EICUDriver *eicup) static void eicu_lld_serve_interrupt(EICUDriver *eicup) {
{
uint16_t sr; uint16_t sr;
sr = eicup->tim->SR; sr = eicup->tim->SR;
@ -125,19 +123,23 @@ static void eicu_lld_serve_interrupt(EICUDriver *eicup)
/* Clear interrupts */ /* Clear interrupts */
eicup->tim->SR = ~sr; eicup->tim->SR = ~sr;
if (eicup->config->input_type == EICU_INPUT_PWM) { switch (eicup->config->input_type) {
case EICU_INPUT_PWM:
if (eicup->config->iccfgp[0] != NULL) { if (eicup->config->iccfgp[0] != NULL) {
if ((sr & STM32_TIM_SR_CC1IF) != 0) if ((sr & STM32_TIM_SR_CC1IF) != 0)
_eicu_isr_invoke_pwm_period_cb(eicup, EICU_CHANNEL_1); _eicu_isr_invoke_pwm_period_cb(eicup,EICU_CHANNEL_1);
if ((sr & STM32_TIM_SR_CC2IF) != 0) if ((sr & STM32_TIM_SR_CC2IF) != 0)
_eicu_isr_invoke_pwm_width_cb(eicup, EICU_CHANNEL_1); _eicu_isr_invoke_pwm_width_cb(eicup, EICU_CHANNEL_1);
} else { }
else {
if ((sr & STM32_TIM_SR_CC1IF) != 0) if ((sr & STM32_TIM_SR_CC1IF) != 0)
_eicu_isr_invoke_pwm_width_cb(eicup, EICU_CHANNEL_2); _eicu_isr_invoke_pwm_width_cb(eicup, EICU_CHANNEL_2);
if ((sr & STM32_TIM_SR_CC2IF) != 0) if ((sr & STM32_TIM_SR_CC2IF) != 0)
_eicu_isr_invoke_pwm_period_cb(eicup, EICU_CHANNEL_2); _eicu_isr_invoke_pwm_period_cb(eicup,EICU_CHANNEL_2);
} }
} else if (eicup->config->input_type == EICU_INPUT_PULSE) { break;
case EICU_INPUT_PULSE:
if ((sr & STM32_TIM_SR_CC1IF) != 0) if ((sr & STM32_TIM_SR_CC1IF) != 0)
_eicu_isr_invoke_pulse_width_cb(eicup, EICU_CHANNEL_1); _eicu_isr_invoke_pulse_width_cb(eicup, EICU_CHANNEL_1);
if ((sr & STM32_TIM_SR_CC2IF) != 0) if ((sr & STM32_TIM_SR_CC2IF) != 0)
@ -146,7 +148,9 @@ static void eicu_lld_serve_interrupt(EICUDriver *eicup)
_eicu_isr_invoke_pulse_width_cb(eicup, EICU_CHANNEL_3); _eicu_isr_invoke_pulse_width_cb(eicup, EICU_CHANNEL_3);
if ((sr & STM32_TIM_SR_CC4IF) != 0) if ((sr & STM32_TIM_SR_CC4IF) != 0)
_eicu_isr_invoke_pulse_width_cb(eicup, EICU_CHANNEL_4); _eicu_isr_invoke_pulse_width_cb(eicup, EICU_CHANNEL_4);
} else { /* EICU_INPUT_EDGE */ break;
case EICU_INPUT_EDGE:
if ((sr & STM32_TIM_SR_CC1IF) != 0) if ((sr & STM32_TIM_SR_CC1IF) != 0)
_eicu_isr_invoke_edge_detect_cb(eicup, EICU_CHANNEL_1); _eicu_isr_invoke_edge_detect_cb(eicup, EICU_CHANNEL_1);
if ((sr & STM32_TIM_SR_CC2IF) != 0) if ((sr & STM32_TIM_SR_CC2IF) != 0)
@ -155,6 +159,11 @@ static void eicu_lld_serve_interrupt(EICUDriver *eicup)
_eicu_isr_invoke_edge_detect_cb(eicup, EICU_CHANNEL_3); _eicu_isr_invoke_edge_detect_cb(eicup, EICU_CHANNEL_3);
if ((sr & STM32_TIM_SR_CC4IF) != 0) if ((sr & STM32_TIM_SR_CC4IF) != 0)
_eicu_isr_invoke_edge_detect_cb(eicup, EICU_CHANNEL_4); _eicu_isr_invoke_edge_detect_cb(eicup, EICU_CHANNEL_4);
break;
default:
osalSysHalt("Unhandled case");
break;
} }
if ((sr & STM32_TIM_SR_UIF) != 0) if ((sr & STM32_TIM_SR_UIF) != 0)
@ -551,7 +560,7 @@ void eicu_lld_start(EICUDriver *eicup) {
((psc + 1) * eicup->config->frequency) == eicup->clock, ((psc + 1) * eicup->config->frequency) == eicup->clock,
"invalid frequency"); "invalid frequency");
eicup->tim->PSC = (uint16_t)psc; eicup->tim->PSC = (uint16_t)psc;
eicup->tim->ARR = 0xFFFF; eicup->tim->ARR = (eicucnt_t)-1;
/* Reset registers */ /* Reset registers */
eicup->tim->SMCR = 0; eicup->tim->SMCR = 0;
@ -574,60 +583,79 @@ void eicu_lld_start(EICUDriver *eicup) {
eicup->tim->CCMR2 = 0; eicup->tim->CCMR2 = 0;
#endif #endif
if (eicup->config->input_type == EICU_INPUT_PWM) /* TIM9 and TIM12 have only 2 channels.*/
{ #if STM32_EICU_USE_TIM9
if (eicup == &EICUD9) {
osalDbgCheck((eicup->config->iccfgp[2] == NULL) &&
(eicup->config->iccfgp[3] == NULL));
}
#endif
#if STM32_EICU_USE_TIM12
if (eicup == &EICUD12) {
osalDbgCheck((eicup->config->iccfgp[2] == NULL) &&
(eicup->config->iccfgp[3] == NULL));
}
#endif
if (eicup->config->input_type == EICU_INPUT_PWM) {
if (eicup->config->iccfgp[0] != NULL) { if (eicup->config->iccfgp[0] != NULL) {
/* Selected input 1. /* Selected input 1.
CCMR1_CC1S = 01 = CH1 Input on TI1. CCMR1_CC1S = 01 = CH1 Input on TI1.
CCMR1_CC2S = 10 = CH2 Input on TI1.*/ CCMR1_CC2S = 10 = CH2 Input on TI1.*/
eicup->tim->CCMR1 = STM32_TIM_CCMR1_CC1S(1) | STM32_TIM_CCMR1_CC2S(2); eicup->tim->CCMR1 = STM32_TIM_CCMR1_CC1S(1) | STM32_TIM_CCMR1_CC2S(2);
/* SMCR_TS = 101, input is TI1FP1. /* SMCR_TS = 101, input is TI1FP1.
SMCR_SMS = 100, reset on rising edge.*/ SMCR_SMS = 100, reset on rising edge.*/
eicup->tim->SMCR = STM32_TIM_SMCR_TS(5) | STM32_TIM_SMCR_SMS(4); eicup->tim->SMCR = STM32_TIM_SMCR_TS(5) | STM32_TIM_SMCR_SMS(4);
/* The CCER settings depend on the selected trigger mode. /* The CCER settings depend on the selected trigger mode.
EICU_INPUT_ACTIVE_HIGH: Active on rising edge, idle on falling edge. EICU_INPUT_ACTIVE_HIGH: Active on rising edge, idle on falling edge.
EICU_INPUT_ACTIVE_LOW: Active on falling edge, idle on rising edge. EICU_INPUT_ACTIVE_LOW: Active on falling edge, idle on rising edge.
*/ */
if (eicup->config->iccfgp[0]->mode == EICU_INPUT_ACTIVE_HIGH) if (eicup->config->iccfgp[0]->mode == EICU_INPUT_ACTIVE_HIGH) {
eicup->tim->CCER = STM32_TIM_CCER_CC1E | eicup->tim->CCER = STM32_TIM_CCER_CC1E |
STM32_TIM_CCER_CC2E | STM32_TIM_CCER_CC2P; STM32_TIM_CCER_CC2E | STM32_TIM_CCER_CC2P;
else }
eicup->tim->CCER = STM32_TIM_CCER_CC1E | STM32_TIM_CCER_CC1P | else {
STM32_TIM_CCER_CC2E; eicup->tim->CCER = STM32_TIM_CCER_CC1E | STM32_TIM_CCER_CC1P |
STM32_TIM_CCER_CC2E;
/* Direct pointers to the capture registers in order to make reading }
data faster from within callbacks.*/
eicup->wccrp[0] = &eicup->tim->CCR[1]; /* Direct pointers to the capture registers in order to make reading
eicup->pccrp = &eicup->tim->CCR[0]; data faster from within callbacks.*/
} else { eicup->wccrp[0] = &eicup->tim->CCR[1];
/* Selected input 2. eicup->pccrp = &eicup->tim->CCR[0];
CCMR1_CC1S = 10 = CH1 Input on TI2. }
CCMR1_CC2S = 01 = CH2 Input on TI2.*/ else {
eicup->tim->CCMR1 = STM32_TIM_CCMR1_CC1S(2) | STM32_TIM_CCMR1_CC2S(1); /* Selected input 2.
CCMR1_CC1S = 10 = CH1 Input on TI2.
/* SMCR_TS = 110, input is TI2FP2. CCMR1_CC2S = 01 = CH2 Input on TI2.*/
SMCR_SMS = 100, reset on rising edge.*/ eicup->tim->CCMR1 = STM32_TIM_CCMR1_CC1S(2) | STM32_TIM_CCMR1_CC2S(1);
eicup->tim->SMCR = STM32_TIM_SMCR_TS(6) | STM32_TIM_SMCR_SMS(4);
/* SMCR_TS = 110, input is TI2FP2.
/* The CCER settings depend on the selected trigger mode. SMCR_SMS = 100, reset on rising edge.*/
EICU_INPUT_ACTIVE_HIGH: Active on rising edge, idle on falling edge. eicup->tim->SMCR = STM32_TIM_SMCR_TS(6) | STM32_TIM_SMCR_SMS(4);
EICU_INPUT_ACTIVE_LOW: Active on falling edge, idle on rising edge.
*/ /* The CCER settings depend on the selected trigger mode.
if (eicup->config->iccfgp[1]->mode == EICU_INPUT_ACTIVE_HIGH) EICU_INPUT_ACTIVE_HIGH: Active on rising edge, idle on falling edge.
eicup->tim->CCER = STM32_TIM_CCER_CC1E | STM32_TIM_CCER_CC1P | EICU_INPUT_ACTIVE_LOW: Active on falling edge, idle on rising edge.
STM32_TIM_CCER_CC2E; */
else if (eicup->config->iccfgp[1]->mode == EICU_INPUT_ACTIVE_HIGH) {
eicup->tim->CCER = STM32_TIM_CCER_CC1E | eicup->tim->CCER = STM32_TIM_CCER_CC1E | STM32_TIM_CCER_CC1P |
STM32_TIM_CCER_CC2E | STM32_TIM_CCER_CC2P; STM32_TIM_CCER_CC2E;
}
else {
eicup->tim->CCER = STM32_TIM_CCER_CC1E |
STM32_TIM_CCER_CC2E | STM32_TIM_CCER_CC2P;
}
/* Direct pointers to the capture registers in order to make reading /* Direct pointers to the capture registers in order to make reading
data faster from within callbacks.*/ data faster from within callbacks.*/
eicup->wccrp[1] = &eicup->tim->CCR[0]; eicup->wccrp[1] = &eicup->tim->CCR[0];
eicup->pccrp = &eicup->tim->CCR[1]; eicup->pccrp = &eicup->tim->CCR[1];
} }
} else { /* EICU_INPUT_EDGE & EICU_INPUT_PULSE */ }
else { /* EICU_INPUT_EDGE & EICU_INPUT_PULSE */
/* Set each input channel that is used as: a normal input capture channel, /* Set each input channel that is used as: a normal input capture channel,
link the corresponding CCR register and set polarity. */ link the corresponding CCR register and set polarity. */
@ -777,29 +805,32 @@ void eicu_lld_enable(EICUDriver *eicup) {
if (eicup->config->period_cb != NULL) if (eicup->config->period_cb != NULL)
eicup->tim->DIER |= STM32_TIM_DIER_CC1IE; eicup->tim->DIER |= STM32_TIM_DIER_CC1IE;
if ((eicup->config->iccfgp[EICU_CHANNEL_1] != NULL) && if ((eicup->config->iccfgp[EICU_CHANNEL_1] != NULL) &&
(eicup->config->iccfgp[EICU_CHANNEL_1]->width_cb != NULL)) (eicup->config->iccfgp[EICU_CHANNEL_1]->capture_cb != NULL))
eicup->tim->DIER |= STM32_TIM_DIER_CC2IE; eicup->tim->DIER |= STM32_TIM_DIER_CC2IE;
} else { }
else {
if ((eicup->config->iccfgp[EICU_CHANNEL_2] != NULL) && if ((eicup->config->iccfgp[EICU_CHANNEL_2] != NULL) &&
(eicup->config->iccfgp[EICU_CHANNEL_2]->width_cb != NULL)) (eicup->config->iccfgp[EICU_CHANNEL_2]->capture_cb != NULL))
eicup->tim->DIER |= STM32_TIM_DIER_CC1IE; eicup->tim->DIER |= STM32_TIM_DIER_CC1IE;
if (eicup->config->period_cb != NULL) if (eicup->config->period_cb != NULL)
eicup->tim->DIER |= STM32_TIM_DIER_CC2IE; eicup->tim->DIER |= STM32_TIM_DIER_CC2IE;
} }
} else { /* EICU_INPUT_PULSE & EICU_INPUT_EDGE */ }
else { /* EICU_INPUT_PULSE || EICU_INPUT_EDGE */
if ((eicup->config->iccfgp[EICU_CHANNEL_1] != NULL) && if ((eicup->config->iccfgp[EICU_CHANNEL_1] != NULL) &&
(eicup->config->iccfgp[EICU_CHANNEL_1]->width_cb != NULL)) (eicup->config->iccfgp[EICU_CHANNEL_1]->capture_cb != NULL))
eicup->tim->DIER |= STM32_TIM_DIER_CC1IE; eicup->tim->DIER |= STM32_TIM_DIER_CC1IE;
if ((eicup->config->iccfgp[EICU_CHANNEL_2] != NULL) && if ((eicup->config->iccfgp[EICU_CHANNEL_2] != NULL) &&
eicup->config->iccfgp[EICU_CHANNEL_2]->width_cb != NULL) (eicup->config->iccfgp[EICU_CHANNEL_2]->capture_cb != NULL))
eicup->tim->DIER |= STM32_TIM_DIER_CC2IE; eicup->tim->DIER |= STM32_TIM_DIER_CC2IE;
if ((eicup->config->iccfgp[EICU_CHANNEL_3] != NULL) && if ((eicup->config->iccfgp[EICU_CHANNEL_3] != NULL) &&
eicup->config->iccfgp[EICU_CHANNEL_3]->width_cb != NULL) (eicup->config->iccfgp[EICU_CHANNEL_3]->capture_cb != NULL))
eicup->tim->DIER |= STM32_TIM_DIER_CC3IE; eicup->tim->DIER |= STM32_TIM_DIER_CC3IE;
if ((eicup->config->iccfgp[EICU_CHANNEL_4] != NULL) && if ((eicup->config->iccfgp[EICU_CHANNEL_4] != NULL) &&
eicup->config->iccfgp[EICU_CHANNEL_4]->width_cb != NULL) (eicup->config->iccfgp[EICU_CHANNEL_4]->capture_cb != NULL))
eicup->tim->DIER |= STM32_TIM_DIER_CC4IE; eicup->tim->DIER |= STM32_TIM_DIER_CC4IE;
} }
if (eicup->config->overflow_cb != NULL) if (eicup->config->overflow_cb != NULL)
eicup->tim->DIER |= STM32_TIM_DIER_UIE; eicup->tim->DIER |= STM32_TIM_DIER_UIE;
@ -822,9 +853,8 @@ void eicu_lld_disable(EICUDriver *eicup) {
} }
/** /**
* @brief Returns the width of the latest pulse. * @brief Returns the time between latest 2 capture events.
* @details The pulse width is defined as number of ticks between the start * @details The time is defined as number of ticks.
* edge and the stop edge.
* *
* @param[in] eicup Pointer to the EICUDriver object. * @param[in] eicup Pointer to the EICUDriver object.
* @param[in] channel The timer channel that fired the interrupt. * @param[in] channel The timer channel that fired the interrupt.
@ -832,21 +862,29 @@ void eicu_lld_disable(EICUDriver *eicup) {
* *
* @notapi * @notapi
*/ */
uint16_t eicu_lld_get_width(EICUDriver *eicup, uint16_t channel) { eicucnt_t eicu_lld_get_time(EICUDriver *eicup, eicuchannel_t channel) {
uint16_t capture, last_count;
capture = eicu_lld_get_compare(eicup, channel);
/* Add code to compensate for overflows when in pulse */ /* Note! there is no overflow check because it handles under the hood of
if (eicup->config->input_type == EICU_INPUT_PULSE) { unsigned subtraction math.*/
last_count = eicup->last_count[channel];
if (capture > last_count) /* No overflow */ /* 16-bit timer */
capture = capture - last_count; if (0xFFFF == eicup->tim->ARR) {
else if (capture < last_count) /* Timer overflow */ uint16_t capture = eicu_lld_get_compare(eicup, channel);
capture = ((0xFFFF - last_count) + capture); uint16_t last_count = eicup->last_count[channel];
uint16_t ret = capture - last_count;
return ret;
}
/* 32-bit timer */
else if (0xFFFFFFFF == eicup->tim->ARR) {
eicucnt_t capture = eicu_lld_get_compare(eicup, channel);
eicucnt_t last_count = eicup->last_count[channel];
return capture - last_count;
}
/* error trap */
else {
osalSysHalt("ARR register must be loaded with maximum possible value");
return 0;
} }
return capture;
} }
#endif /* HAL_USE_EICU */ #endif /* HAL_USE_EICU */

View File

@ -257,32 +257,17 @@
* @brief EICU driver mode. * @brief EICU driver mode.
*/ */
typedef enum { typedef enum {
/** EICU_INPUT_ACTIVE_HIGH = 0, /**< Trigger on rising edge. */
* @brief Trigger on rising edge. EICU_INPUT_ACTIVE_LOW = 1, /**< Trigger on falling edge. */
*/
EICU_INPUT_ACTIVE_HIGH = 0,
/**
* @brief Trigger on falling edge.
*/
EICU_INPUT_ACTIVE_LOW = 1,
} eicumode_t; } eicumode_t;
/** /**
* @brief Input type selector. * @brief Input type selector.
*/ */
typedef enum { typedef enum {
/** EICU_INPUT_EDGE = 0, /**< Triggers on the edge of the input.*/
* @brief Triggers on the edge of the input. EICU_INPUT_PULSE = 1, /**< Triggers on detected pulse.*/
*/ EICU_INPUT_PWM = 2 /**< Triggers on detected PWM period and width. */
EICU_INPUT_EDGE = 0,
/**
* @brief Triggers on detected pulse.
*/
EICU_INPUT_PULSE = 1,
/**
* @brief Triggers on detected PWM period and width.
*/
EICU_INPUT_PWM = 2
} eicuinput_t; } eicuinput_t;
/** /**
@ -293,10 +278,10 @@ typedef uint32_t eicufreq_t;
/** /**
* @brief EICU counter type. * @brief EICU counter type.
*/ */
typedef uint16_t eicucnt_t; typedef uint32_t eicucnt_t;
/** /**
* @brief EICU Input Capture Settings structure definition. * @brief EICU Capture Channel Config structure definition.
*/ */
typedef struct { typedef struct {
/** /**
@ -305,16 +290,15 @@ typedef struct {
eicumode_t mode; eicumode_t mode;
/** /**
* @brief Capture event callback. Used for PWM width, pulse width and * @brief Capture event callback. Used for PWM width, pulse width and
* normal capture event. * pulse period capture event.
*/ */
eicucallback_t width_cb; eicucallback_t capture_cb;
} EICU_IC_Settings; } EICUChannelConfig;
/** /**
* @brief EICU Input Capture Config structure definition. * @brief EICU Config structure definition.
*/ */
typedef struct typedef struct {
{
/** /**
* @brief Select which input type the driver will be configured for. * @brief Select which input type the driver will be configured for.
*/ */
@ -328,10 +312,10 @@ typedef struct
* @note A NULL parameter indicates the channel as unused. * @note A NULL parameter indicates the channel as unused.
* @note In PWM mode, only Channel 1 OR Channel 2 may be used. * @note In PWM mode, only Channel 1 OR Channel 2 may be used.
*/ */
const EICU_IC_Settings *iccfgp[4]; const EICUChannelConfig *iccfgp[4];
/** /**
* @brief Period capture event callback. * @brief Period capture event callback.
* @note Only used when in PWM measuremtent mode * @note Only used when in PWM measurement mode
*/ */
eicucallback_t period_cb; eicucallback_t period_cb;
/** /**
@ -345,10 +329,9 @@ typedef struct
} EICUConfig; } EICUConfig;
/** /**
* @brief EICU Input Capture Driver structure definition * @brief EICU Driver structure definition
*/ */
struct EICUDriver struct EICUDriver {
{
/** /**
* @brief STM32 timer peripheral for Input Capture. * @brief STM32 timer peripheral for Input Capture.
*/ */
@ -358,7 +341,7 @@ struct EICUDriver
*/ */
eicustate_t state; eicustate_t state;
/** /**
* @brief Temporary width holder during pulse measurement. * @brief Temporary width holder during measurement.
*/ */
eicucnt_t last_count[4]; eicucnt_t last_count[4];
/** /**
@ -416,7 +399,7 @@ struct EICUDriver
* @notapi * @notapi
*/ */
#define eicu_lld_invert_polarity(eicup, channel) \ #define eicu_lld_invert_polarity(eicup, channel) \
(eicup)->tim->CCER ^= ((uint16_t)(STM32_TIM_CCER_CC1P << ((channel) * 4))) (eicup)->tim->CCER ^= ((uint16_t)(STM32_TIM_CCER_CC1P << ((channel) * 4)))
/*===========================================================================*/ /*===========================================================================*/
/* External declarations. */ /* External declarations. */
@ -461,7 +444,7 @@ extern "C" {
void eicu_lld_stop(EICUDriver *eicup); void eicu_lld_stop(EICUDriver *eicup);
void eicu_lld_enable(EICUDriver *eicup); void eicu_lld_enable(EICUDriver *eicup);
void eicu_lld_disable(EICUDriver *eicup); void eicu_lld_disable(EICUDriver *eicup);
uint16_t eicu_lld_get_width(EICUDriver *eicup, uint16_t channel); eicucnt_t eicu_lld_get_time(EICUDriver *eicup, eicuchannel_t channel);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -138,8 +138,8 @@ void eicuDisable(EICUDriver *eicup) {
osalDbgCheck(eicup != NULL); osalDbgCheck(eicup != NULL);
osalSysLock(); osalSysLock();
osalDbgAssert((eicup->state == EICU_READY) || (eicup->state == EICU_WAITING) || osalDbgAssert((eicup->state == EICU_READY) || (eicup->state == EICU_IDLE) ||
(eicup->state == EICU_ACTIVE) || (eicup->state == EICU_IDLE), (eicup->state == EICU_ACTIVE) || (eicup->state == EICU_WAITING),
"invalid state"); "invalid state");
eicu_lld_disable(eicup); eicu_lld_disable(eicup);
eicup->state = EICU_READY; eicup->state = EICU_READY;