aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/ports/STM32
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2014-08-31 14:24:12 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2014-08-31 14:24:12 +0000
commit87e4b85755680a122f690f445b8cb320ca4f05ad (patch)
tree7f214955a0eda60f7fae53af8557a683bd277ba0 /os/hal/ports/STM32
parentcb1f7893a41f24a46d0bc99198a3281dcea2148d (diff)
downloadChibiOS-87e4b85755680a122f690f445b8cb320ca4f05ad.tar.gz
ChibiOS-87e4b85755680a122f690f445b8cb320ca4f05ad.tar.bz2
ChibiOS-87e4b85755680a122f690f445b8cb320ca4f05ad.zip
Improvements to the ICU driver (not finished).
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7210 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal/ports/STM32')
-rw-r--r--os/hal/ports/STM32/LLD/TIMv1/icu_lld.c105
-rw-r--r--os/hal/ports/STM32/LLD/TIMv1/icu_lld.h7
2 files changed, 90 insertions, 22 deletions
diff --git a/os/hal/ports/STM32/LLD/TIMv1/icu_lld.c b/os/hal/ports/STM32/LLD/TIMv1/icu_lld.c
index 1e935fd54..1602ac1d1 100644
--- a/os/hal/ports/STM32/LLD/TIMv1/icu_lld.c
+++ b/os/hal/ports/STM32/LLD/TIMv1/icu_lld.c
@@ -596,43 +596,108 @@ void icu_lld_stop(ICUDriver *icup) {
}
/**
- * @brief Enables the input capture.
+ * @brief Starts the input capture.
*
* @param[in] icup pointer to the @p ICUDriver object
*
* @notapi
*/
-void icu_lld_enable(ICUDriver *icup) {
+void icu_lld_start_capture(ICUDriver *icup) {
+ /* Triggering an UG and clearing the IRQ status.*/
icup->tim->EGR |= STM32_TIM_EGR_UG;
- icup->tim->SR = 0; /* Clear pending IRQs (if any). */
- if (icup->config->channel == ICU_CHANNEL_1) {
- if (icup->config->period_cb != NULL)
- icup->tim->DIER |= STM32_TIM_DIER_CC1IE;
- if (icup->config->width_cb != NULL)
- icup->tim->DIER |= STM32_TIM_DIER_CC2IE;
- } else {
- if (icup->config->width_cb != NULL)
- icup->tim->DIER |= STM32_TIM_DIER_CC1IE;
- if (icup->config->period_cb != NULL)
- icup->tim->DIER |= STM32_TIM_DIER_CC2IE;
- }
- if (icup->config->overflow_cb != NULL)
- icup->tim->DIER |= STM32_TIM_DIER_UIE;
+ icup->tim->SR = 0;
+
+ /* Timer is started.*/
icup->tim->CR1 = STM32_TIM_CR1_URS | STM32_TIM_CR1_CEN;
}
/**
- * @brief Disables the input capture.
+ * @brief Waits for the first cycle activation edge.
+ * @details The function waits for the next PWM input activation front then
+ * 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.
*
* @param[in] icup pointer to the @p ICUDriver object
*
* @notapi
*/
-void icu_lld_disable(ICUDriver *icup) {
+void icu_lld_wait_capture(ICUDriver *icup) {
+
+}
+
+/**
+ * @brief Stops the input capture.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+void icu_lld_stop_capture(ICUDriver *icup) {
+
+ /* Timer stopped.*/
+ icup->tim->CR1 = 0;
+
+ /* All interrupts disabled.*/
+ icup->tim->DIER &= ~STM32_TIM_DIER_IRQ_MASK;
+}
+
+/**
+ * @brief Enables notifications.
+ * @pre The ICU unit must have been activated using @p icuStart().
+ * @note If the notification is already enabled then the call has no effect.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @api
+ */
+void icu_enable_notifications(ICUDriver *icup) {
+ uint32_t dier = icup->tim->DIER;
+
+ /* 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) {
+ /* Previously triggered IRQs are ignored, status cleared.*/
+ icup->tim->SR = 0;
+
+ if (icup->config->channel == ICU_CHANNEL_1) {
+ /* Enabling periodic callback on CC1.*/
+ dier |= STM32_TIM_DIER_CC1IE;
+
+ /* Optionally enabling width callback on CC2.*/
+ if (icup->config->width_cb != NULL)
+ dier |= STM32_TIM_DIER_CC2IE;
+ } else {
+ /* Enabling periodic callback on CC2.*/
+ dier |= STM32_TIM_DIER_CC2IE;
+
+ /* Optionally enabling width callback on CC1.*/
+ if (icup->config->width_cb != NULL)
+ dier |= STM32_TIM_DIER_CC1IE;
+ }
+
+ /* If an overflow callback is defined then also the overflow callback
+ is enabled.*/
+ if (icup->config->overflow_cb != NULL)
+ dier |= STM32_TIM_DIER_UIE;
- icup->tim->CR1 = 0; /* Initially stopped. */
- icup->tim->SR = 0; /* Clear pending IRQs (if any). */
+ /* One single atomic write.*/
+ icup->tim->DIER = dier;
+ }
+}
+
+/**
+ * @brief Disables notifications.
+ * @pre The ICU unit must have been activated using @p icuStart().
+ * @note If the notification is already disabled then the call has no effect.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @api
+ */
+void icu_disable_notifications(ICUDriver *icup) {
/* All interrupts disabled.*/
icup->tim->DIER &= ~STM32_TIM_DIER_IRQ_MASK;
diff --git a/os/hal/ports/STM32/LLD/TIMv1/icu_lld.h b/os/hal/ports/STM32/LLD/TIMv1/icu_lld.h
index 87b5dfd4d..2559e9643 100644
--- a/os/hal/ports/STM32/LLD/TIMv1/icu_lld.h
+++ b/os/hal/ports/STM32/LLD/TIMv1/icu_lld.h
@@ -399,8 +399,11 @@ extern "C" {
void icu_lld_init(void);
void icu_lld_start(ICUDriver *icup);
void icu_lld_stop(ICUDriver *icup);
- void icu_lld_enable(ICUDriver *icup);
- void icu_lld_disable(ICUDriver *icup);
+ void icu_lld_start_capture(ICUDriver *icup);
+ void icu_lld_wait_capture(ICUDriver *icup);
+ void icu_lld_stop_capture(ICUDriver *icup);
+ void icu_enable_notifications(ICUDriver *icup);
+ void icu_disable_notifications(ICUDriver *icup);
#ifdef __cplusplus
}
#endif