diff options
author | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2014-08-31 14:24:12 +0000 |
---|---|---|
committer | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2014-08-31 14:24:12 +0000 |
commit | 87e4b85755680a122f690f445b8cb320ca4f05ad (patch) | |
tree | 7f214955a0eda60f7fae53af8557a683bd277ba0 /os/hal/ports/STM32/LLD | |
parent | cb1f7893a41f24a46d0bc99198a3281dcea2148d (diff) | |
download | ChibiOS-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/LLD')
-rw-r--r-- | os/hal/ports/STM32/LLD/TIMv1/icu_lld.c | 105 | ||||
-rw-r--r-- | os/hal/ports/STM32/LLD/TIMv1/icu_lld.h | 7 |
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
|