From ff676aee33d4061e9d8186a15ad72c78fa1466a0 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 28 Mar 2011 15:32:56 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2848 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/dox/adc.dox | 4 +- os/hal/dox/can.dox | 4 +- os/hal/dox/gpt.dox | 7 +- os/hal/dox/hal.dox | 21 ++-- os/hal/dox/i2c.dox | 5 +- os/hal/dox/icu.dox | 115 ++++++++++++++++++++ os/hal/dox/pwm.dox | 3 +- os/hal/dox/spi.dox | 6 +- os/hal/dox/uart.dox | 4 +- os/hal/dox/usb.dox | 4 +- os/hal/include/icu.h | 131 ++++++++++++++++++++++ os/hal/platforms/STM32/icu_lld.c | 221 +++++++++++++++++++++++++++++++++++++ os/hal/platforms/STM32/icu_lld.h | 230 +++++++++++++++++++++++++++++++++++++++ os/hal/src/icu.c | 151 +++++++++++++++++++++++++ os/hal/templates/icu_lld.c | 145 ++++++++++++++++++++++++ os/hal/templates/icu_lld.h | 136 +++++++++++++++++++++++ readme.txt | 2 + 17 files changed, 1162 insertions(+), 27 deletions(-) create mode 100644 os/hal/dox/icu.dox create mode 100644 os/hal/include/icu.h create mode 100644 os/hal/platforms/STM32/icu_lld.c create mode 100644 os/hal/platforms/STM32/icu_lld.h create mode 100644 os/hal/src/icu.c create mode 100644 os/hal/templates/icu_lld.c create mode 100644 os/hal/templates/icu_lld.h diff --git a/os/hal/dox/adc.dox b/os/hal/dox/adc.dox index f5b83532d..0d6770f64 100644 --- a/os/hal/dox/adc.dox +++ b/os/hal/dox/adc.dox @@ -21,8 +21,8 @@ /** * @defgroup ADC ADC Driver * @brief Generic ADC Driver. - * @details This module implements a generic ADC driver supporting a - * variety of buffer and conversion modes. + * @details This module implements a generic ADC (Analog to Digital Converter) + * driver supporting a variety of buffer and conversion modes. * @pre In order to use the ADC driver the @p HAL_USE_ADC option * must be enabled in @p halconf.h. * diff --git a/os/hal/dox/can.dox b/os/hal/dox/can.dox index f32630442..1a0c81c0d 100644 --- a/os/hal/dox/can.dox +++ b/os/hal/dox/can.dox @@ -21,8 +21,8 @@ /** * @defgroup CAN CAN Driver * @brief Generic CAN Driver. - * @details This module implements a generic CAN driver allowing the exchange - * of information at frame level. + * @details This module implements a generic CAN (Controller Area Network) + * driver allowing the exchange of information at frame level. * @pre In order to use the CAN driver the @p HAL_USE_CAN option * must be enabled in @p halconf.h. * diff --git a/os/hal/dox/gpt.dox b/os/hal/dox/gpt.dox index 203f7a647..d51ad6af3 100644 --- a/os/hal/dox/gpt.dox +++ b/os/hal/dox/gpt.dox @@ -21,9 +21,10 @@ /** * @defgroup GPT GPT Driver * @brief Generic GPT Driver. - * @details This module implements a generic timer driver. The timer can be - * programmed in order to trigger callbacks after a specified time - * period or continuously with a specified interval. + * @details This module implements a generic GPT (General Purpose Timer) + * driver. The timer can be programmed in order to trigger callbacks + * after a specified time period or continuously with a specified + * interval. * @pre In order to use the GPT driver the @p HAL_USE_GPT option * must be enabled in @p halconf.h. * diff --git a/os/hal/dox/hal.dox b/os/hal/dox/hal.dox index d08f10bcd..15b4401fb 100644 --- a/os/hal/dox/hal.dox +++ b/os/hal/dox/hal.dox @@ -20,16 +20,17 @@ /** * @defgroup HAL HAL Driver - * @brief Hardware Abstraction Layer. - * @details The HAL driver performs the system initialization and includes - * the platform support code shared by the other drivers. This driver does - * contain any API function except for a general initialization function - * @p halInit() that must be invoked before any HAL service can be used, - * usually the HAL initialization should be performed immediately before the - * kernel initialization.
- * Some HAL driver implementations also offer a custom early clock - * setum function that can be invoked before the C runtime initialization - * in order to accellerate the startup time. + * @brief Hardware Abstraction Layer. + * @details The HAL (Hardware Abstraction Layer) driver performs the system + * initialization and includes the platform support code shared by + * the other drivers. This driver does contain any API function + * except for a general initialization function @p halInit() that + * must be invoked before any HAL service can be used, usually the + * HAL initialization should be performed immediately before the + * kernel initialization.
+ * Some HAL driver implementations also offer a custom early clock + * setup function that can be invoked before the C runtime + * initialization in order to accelerate the startup time. * * @ingroup IO */ diff --git a/os/hal/dox/i2c.dox b/os/hal/dox/i2c.dox index 391fbb62e..1ffd2da47 100644 --- a/os/hal/dox/i2c.dox +++ b/os/hal/dox/i2c.dox @@ -20,8 +20,9 @@ /** * @defgroup I2C I2C Driver - * @brief Generic I2C Driver. - * @details This module implements a generic I2C driver. + * @brief Generic I2C Driver. + * @details This module implements a generic I2C (Inter-Integrated Circuit) + * driver. * @pre In order to use the I2C driver the @p HAL_USE_I2C option * must be enabled in @p halconf.h. * diff --git a/os/hal/dox/icu.dox b/os/hal/dox/icu.dox new file mode 100644 index 000000000..c90dc237d --- /dev/null +++ b/os/hal/dox/icu.dox @@ -0,0 +1,115 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @defgroup ICU ICU Driver + * @brief Generic ICU Driver. + * @details This module implements a generic ICU (Input Capture Unit) driver. + * @pre In order to use the ICU driver the @p HAL_USE_ICU option + * must be enabled in @p halconf.h. + * + * @section icu_1 Driver State Machine + * The driver implements a state machine internally, not all the driver + * functionalities can be used in any moment, any transition not explicitly + * shown in the following diagram has to be considered an error and shall + * be captured by an assertion (if enabled). + * @if LATEX_PDF + * @dot + digraph example { + size="5, 7"; + rankdir="LR"; + + node [shape=circle, fontname=Sans, fontsize=8, fixedsize="true", width="0.9", height="0.9"]; + edge [fontname=Sans, fontsize=8]; + + stop [label="ICU_STOP\nLow Power"]; + uninit [label="ICU_UNINIT", style="bold"]; + ready [label="ICU_READY\nClock Enabled"]; + waiting [label="ICU_WAITING"]; + active [label="ICU_ACTIVE"]; + idle [label="ICU_IDLE"]; + + uninit -> stop [label=" icuInit()", constraint=false]; + stop -> stop [label="\nicuStop()"]; + stop -> ready [label="\nicuStart()"]; + ready -> stop [label="\nicuStop()"]; + ready -> ready [label="\nicuStart()\nicuDisable()"]; + ready -> waiting [label="\nicuEnable()"]; + waiting -> active [label="\nStart Front"]; + waiting -> ready [label="\nicuDisable()"]; + active -> idle [label="\nStop Front\n>width_cb<"]; + active -> ready [label="\nicuDisable()\nicuDisableI()"]; + idle -> active [label="\nStart Front\n>period_cb<"]; + idle -> ready [label="\nicuDisable()\nicuDisableI()"]; + } + * @enddot + * @else + * @dot + digraph example { + rankdir="LR"; + + node [shape=circle, fontname=Sans, fontsize=8, fixedsize="true", width="0.9", height="0.9"]; + edge [fontname=Sans, fontsize=8]; + + stop [label="ICU_STOP\nLow Power"]; + uninit [label="ICU_UNINIT", style="bold"]; + ready [label="ICU_READY\nClock Enabled"]; + waiting [label="ICU_WAITING"]; + active [label="ICU_ACTIVE"]; + idle [label="ICU_IDLE"]; + + uninit -> stop [label=" icuInit()", constraint=false]; + stop -> stop [label="\nicuStop()"]; + stop -> ready [label="\nicuStart()"]; + ready -> stop [label="\nicuStop()"]; + ready -> ready [label="\nicuStart()\nicuDisable()"]; + ready -> waiting [label="\nicuEnable()"]; + waiting -> active [label="\nStart Front"]; + waiting -> ready [label="\nicuDisable()"]; + active -> idle [label="\nStop Front\n>width_cb<"]; + active -> ready [label="\nicuDisable()\nicuDisableI()"]; + idle -> active [label="\nStart Front\n>period_cb<"]; + idle -> ready [label="\nicuDisable()\nicuDisableI()"]; + } + * @enddot + * @endif + * + * @section icu_2 ICU Operations. + * This driver abstracts a generic Input Capture Unit composed of: + * - A clock prescaler. + * - A main up counter. + * - Two capture registers triggered by the rising and falling edges on + * the sampled input. + * . + * The ICU unit can be programmed to synchronize on the rising or falling + * edge of the sample input: + * - ICU_INPUT_ACTIVE_HIGH, a rising edge is the start signal. + * - ICU_INPUT_ACTIVE_LOW, a falling edge is the start signal. + * . + * After the activation the ICU unit can be in one of the following + * states at any time: + * - ICU_WAITING, waiting the first start signal. + * - ICU_ACTIVE, after a start signal. + * - ICU_IDLE, after a stop signal. + * . + * Callbacks are invoked when start or stop signals occur. + * + * @ingroup IO + */ diff --git a/os/hal/dox/pwm.dox b/os/hal/dox/pwm.dox index 3f2bdfd71..fbf61ca9f 100644 --- a/os/hal/dox/pwm.dox +++ b/os/hal/dox/pwm.dox @@ -21,7 +21,8 @@ /** * @defgroup PWM PWM Driver * @brief Generic PWM Driver. - * @details This module implements a generic PWM driver. + * @details This module implements a generic PWM (Pulse Width Modulation) + * driver. * @pre In order to use the PWM driver the @p HAL_USE_PWM option * must be enabled in @p halconf.h. * diff --git a/os/hal/dox/spi.dox b/os/hal/dox/spi.dox index cd462b8ae..047ff646e 100644 --- a/os/hal/dox/spi.dox +++ b/os/hal/dox/spi.dox @@ -21,9 +21,9 @@ /** * @defgroup SPI SPI Driver * @brief Generic SPI Driver. - * @details This module implements a generic SPI driver allowing bidirectional - * and monodirectional transfers, complex atomic transactions are - * supported as well. + * @details This module implements a generic SPI (Serial Peripheral Interface) + * driver allowing bidirectional and monodirectional transfers, + * complex atomic transactions are supported as well. * @pre In order to use the SPI driver the @p HAL_USE_SPI option * must be enabled in @p halconf.h. * diff --git a/os/hal/dox/uart.dox b/os/hal/dox/uart.dox index fe7a31534..7fea38dcb 100644 --- a/os/hal/dox/uart.dox +++ b/os/hal/dox/uart.dox @@ -21,8 +21,8 @@ /** * @defgroup UART UART Driver * @brief Generic UART Driver. - * @details This driver abstracts a generic UART peripheral, the API is - * designed to be: + * @details This driver abstracts a generic UART (Universal Asynchronous + * Receiver Transmitter) peripheral, the API is designed to be: * - Unbuffered and copy-less, transfers are always directly performed * from/to the application-level buffers without extra copy * operations. diff --git a/os/hal/dox/usb.dox b/os/hal/dox/usb.dox index ebf2042a0..62b3aaf12 100644 --- a/os/hal/dox/usb.dox +++ b/os/hal/dox/usb.dox @@ -21,8 +21,8 @@ /** * @defgroup USB USB Driver * @brief Generic USB Driver. - * @details This module implements a generic USB driver supporting device-mode - * operations. + * @details This module implements a generic USB (Universal Serial Bus) driver + * supporting device-mode operations. * @pre In order to use the USB driver the @p HAL_USE_USB option * must be enabled in @p halconf.h. * diff --git a/os/hal/include/icu.h b/os/hal/include/icu.h new file mode 100644 index 000000000..1f4e58ece --- /dev/null +++ b/os/hal/include/icu.h @@ -0,0 +1,131 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file icu.h + * @brief ICU Driver macros and structures. + * + * @addtogroup ICU + * @{ + */ + +#ifndef _ICU_H_ +#define _ICU_H_ + +#if HAL_USE_ICU || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Driver state machine possible states. + */ +typedef enum { + ICU_UNINIT = 0, /**< Not initialized. */ + ICU_STOP = 1, /**< Stopped. */ + ICU_READY = 2, /**< Ready. */ + ICU_WAITING = 3, /**< Waiting first edge. */ + ICU_ACTIVE = 4, /**< Active cycle phase. */ + ICU_IDLE = 5, /**< Idle cycle phase. */ +} icustate_t; + +#include "icu_lld.h" + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @brief Enables the input capture. + * + * @param[in] icup pointer to the @p ICUDriver object + * + * @iclass + */ +void icuEnableI(icup) icu_lld_enable(icup) + +/** + * @brief Disables the input capture. + * + * @param[in] icup pointer to the @p ICUDriver object + * + * @iclass + */ +void icuDisableI(ICUDriver *icup) icu_lld_disable(icup) + +/** + * @brief Returns the width of the latest pulse. + * @details The pulse width is defined as number of ticks between the start + * edge and the stop edge. + * + * @param[in] icup pointer to the @p ICUDriver object + * @return The number of ticks. + * + * @iclass + */ +#define icuGetWidthI(icup) icu_lld_get_width(icup) + +/** + * @brief Returns the width of the latest cycle. + * @details The cycle width is defined as number of ticks between a start + * edge and the next start edge. + * + * @param[in] icup pointer to the @p ICUDriver object + * @return The number of ticks. + * + * @iclass + */ +#define icuGetPeriodI(icup) icu_lld_get_period(icup) + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void icuInit(void); + void icuObjectInit(ICUDriver *icup); + void icuStart(ICUDriver *icup, const ICUConfig *config); + void icuStop(ICUDriver *icup); + void icuEnableI(ICUDriver *icup); + void icuDisableI(ICUDriver *icup); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_ICU */ + +#endif /* _ICU_H_ */ + +/** @} */ diff --git a/os/hal/platforms/STM32/icu_lld.c b/os/hal/platforms/STM32/icu_lld.c new file mode 100644 index 000000000..6877b2d72 --- /dev/null +++ b/os/hal/platforms/STM32/icu_lld.c @@ -0,0 +1,221 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file STM32/icu_lld.c + * @brief STM32 ICU subsystem low level driver header. + * + * @addtogroup ICU + * @{ + */ + +#include "ch.h" +#include "hal.h" + +#if HAL_USE_ICU || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief ICU1 driver identifier. + * @note The driver ICUD1 allocates the complex timer TIM1 when enabled. + */ +#if STM32_ICU_USE_TIM1 || defined(__DOXYGEN__) +ICUDriver ICUD1; +#endif + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if STM32_ICU_USE_TIM1 +/** + * @brief TIM1 update interrupt handler. + * @note It is assumed that this interrupt is only activated if the callback + * pointer is not equal to @p NULL in order to not perform an extra + * check in a potentially critical interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(TIM1_UP_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + TIM1->SR = ~TIM_SR_UIF; + ICUD1.config->callback(&ICUD1); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief TIM1 compare interrupt handler. + * @note It is assumed that the various sources are only activated if the + * associated callback pointer is not equal to @p NULL in order to not + * perform an extra check in a potentially critical interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(TIM1_CC_IRQHandler) { + uint16_t sr; + + CH_IRQ_PROLOGUE(); + + sr = TIM1->SR & TIM1->DIER; + TIM1->SR = ~(TIM_SR_CC1IF | TIM_SR_CC2IF | TIM_SR_CC3IF | TIM_SR_CC4IF); + if ((sr & TIM_SR_CC1IF) != 0) + ICUD1.config->channels[0].callback(&ICUD1); + if ((sr & TIM_SR_CC2IF) != 0) + ICUD1.config->channels[1].callback(&ICUD1); + + CH_IRQ_EPILOGUE(); +} +#endif /* STM32_ICU_USE_TIM1 */ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level ICU driver initialization. + * + * @notapi + */ +void icu_lld_init(void) { + +#if STM32_ICU_USE_TIM1 + /* Driver initialization.*/ + icuObjectInit(&ICUD1); + ICUD1.tim = TIM1; +#endif +} + +/** + * @brief Configures and activates the ICU peripheral. + * + * @param[in] icup pointer to the @p ICUDriver object + * + * @notapi + */ +void icu_lld_start(ICUDriver *icup) { + + if (icup->state == ICU_STOP) { + /* Clock activation and timer reset.*/ +#if STM32_ICU_USE_TIM1 + if (&ICUD1 == icup) { + RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; + RCC->APB2RSTR = RCC_APB2RSTR_TIM1RST; + RCC->APB2RSTR = 0; + NVICEnableVector(TIM1_UP_IRQn, + CORTEX_PRIORITY_MASK(STM32_ICU_TIM1_IRQ_PRIORITY)); + NVICEnableVector(TIM1_CC_IRQn, + CORTEX_PRIORITY_MASK(STM32_ICU_TIM1_IRQ_PRIORITY)); + } +#endif + } + + /* Timer configuration, PWM input mode.*/ + icup->tim->CR1 = 0; /* Initially stopped. */ + icup->tim->CR2 = 0; + icup->tim->ARR = 0xFFFF; + icup->tim->PSC = icup->config->psc; /* Prescaler value. */ + icup->tim->DIER = 0; + /* CCMR1_CC1S = 01 = CH1 Input on TI1. + CCMR1_CC2S = 10 = CH2 Input on TI2.*/ + icup->tim->CCMR1 = TIM_CCMR1_CC1S_0 | + TIM_CCMR1_CC2S_1; + /* SMCR_TS = 101, input is TI1FP1. + SMCR_SMS = 100, reset on rising edge.*/ + icup->tim->SMCR = TIM_SMCR_TS_2 | TIM_SMCR_TS_0 | + TIM_SMCR_SMS_2. + /* The CCER settings depend on the selected trigger mode. + ICU_INPUT_ACTIVE_HIGH: Active on rising edge, idle on falling edge. + ICU_INPUT_ACTIVE_LOW: Active on falling edge, idle on rising edge.*/ + if (icup->config->mode == ICU_INPUT_ACTIVE_HIGH) + icup->tim->CCER = TIM_CCER_CC1E | + TIM_CCER_CC2E | TIM_CCER_CC2P; + else + icup->tim->CCER = TIM_CCER_CC1E | TIM_CCER_CC1P + TIM_CCER_CC2E; +} + +/** + * @brief Deactivates the ICU peripheral. + * + * @param[in] icup pointer to the @p ICUDriver object + * + * @notapi + */ +void icu_lld_stop(ICUDriver *icup) { + + if (icup->state == ICU_READY) { + /* Clock deactivation.*/ + icup->tim->CR1 = 0; /* Timer disabled. */ + icup->tim->DIER = 0; /* All IRQs disabled. */ + +#if STM32_ICU_USE_TIM1 + if (&ICUD1 == icup) { + NVICDisableVector(TIM1_UP_IRQn); + RCC->APB2ENR &= ~RCC_APB2ENR_TIM1EN; + } +#endif + } +} + +/** + * @brief Enables the input capture. + * + * @param[in] icup pointer to the @p ICUDriver object + * + * @notapi + */ +void icu_lld_enable(ICUDriver *icup) { + + icup->tim->SR = 0; /* Clear pending IRQs (if any). */ + icup->tim->DIER = TIM_DIER_CC1IE | TIM_DIER_CC2IE; + icup->tim->CR1 = TIM_CR1_URS | TIM_CR1_CEN; +} + +/** + * @brief Disables the input capture. + * + * @param[in] icup pointer to the @p ICUDriver object + * + * @notapi + */ +void icu_lld_disable(ICUDriver *icup) { + + icup->tim->CR1 = 0; /* Initially stopped. */ + icup->tim->SR = 0; /* Clear pending IRQs (if any). */ + icup->tim->DIER = 0; /* Interrupts disabled. */ +} + +#endif /* HAL_USE_ICU */ + +/** @} */ diff --git a/os/hal/platforms/STM32/icu_lld.h b/os/hal/platforms/STM32/icu_lld.h new file mode 100644 index 000000000..78efa9765 --- /dev/null +++ b/os/hal/platforms/STM32/icu_lld.h @@ -0,0 +1,230 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file STM32/icu_lld.h + * @brief STM32 ICU subsystem low level driver header. + * + * @addtogroup ICU + * @{ + */ + +#ifndef _ICU_LLD_H_ +#define _ICU_LLD_H_ + +#if HAL_USE_ICU || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @brief ICUD1 driver enable switch. + * @details If set to @p TRUE the support for ICUD1 is included. + * @note The default is @p TRUE. + */ +#if !defined(STM32_ICU_USE_TIM1) || defined(__DOXYGEN__) +#define STM32_ICU_USE_TIM1 TRUE +#endif + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if STM32_ICU_USE_TIM1 && !STM32_HAS_TIM1 +#error "TIM1 not present in the selected device" +#endif + +#if STM32_ICU_USE_TIM2 && !STM32_HAS_TIM2 +#error "TIM2 not present in the selected device" +#endif + +#if STM32_ICU_USE_TIM3 && !STM32_HAS_TIM3 +#error "TIM3 not present in the selected device" +#endif + +#if STM32_ICU_USE_TIM4 && !STM32_HAS_TIM4 +#error "TIM4 not present in the selected device" +#endif + +#if STM32_ICU_USE_TIM5 && !STM32_HAS_TIM5 +#error "TIM5 not present in the selected device" +#endif + +#if !STM32_ICU_USE_TIM1 && !STM32_ICU_USE_TIM2 && \ + !STM32_ICU_USE_TIM3 && !STM32_ICU_USE_TIM4 && \ + !STM32_ICU_USE_TIM5 +#error "ICU driver activated but no TIM peripheral assigned" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief ICU driver mode. + */ +typedef enum { + ICU_INPUT_ACTIVE_HIGH = 0, /**< Trigger on rising edge. */ + ICU_INPUT_ACTIVE_LOW = 1, /**< Trigger on falling edge. */ +} icumode_t; + +/** + * @brief ICU counter type. + */ +typedef uint16_t icucnt_t; + +/** + * @brief Type of a structure representing an ICU driver. + */ +typedef struct ICUDriver ICUDriver; + +/** + * @brief ICU notification callback type. + * + * @param[in] icup pointer to a @p ICUDriver object + */ +typedef void (*icucallback_t)(ICUDriver *icup); + +/** + * @brief Driver configuration structure. + * @note It could be empty on some architectures. + */ +typedef struct { + /** + * @brief Driver mode. + */ + icumode_t mode; + /** + * @brief Callback for pulse width measurement. + */ + icucallback_t width_cb; + /** + * @brief Callback for cycle period measurement. + */ + icucallback_t period_cb; + /* End of the mandatory fields.*/ + /** + * @brief TIM PSC (pre-scaler) register initialization data. + */ + uint16_t psc; +} ICUConfig; + +/** + * @brief Structure representing an ICU driver. + */ +struct ICUDriver { + /** + * @brief Driver state. + */ + icustate_t state; + /** + * @brief Current configuration data. + */ + const ICUConfig *config; + /* End of the mandatory fields.*/ + /** + * @brief Pointer to the TIMx registers block. + */ + TIM_TypeDef *tim; +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + + +/** + * @brief Returns the width of the latest pulse. + * @details The pulse width is defined as number of ticks between the start + * edge and the stop edge. + * + * @param[in] icup pointer to the @p ICUDriver object + * @return The number of ticks. + * + * @notapi + */ +#define icu_lld_get_width(icup) ((icup)->tim->CCR2) + +/** + * @brief Returns the width of the latest cycle. + * @details The cycle width is defined as number of ticks between a start + * edge and the next start edge. + * + * @param[in] icup pointer to the @p ICUDriver object + * @return The number of ticks. + * + * @notapi + */ +#define icu_lld_get_period(icup) ((icup)->tim->CCR1) + +/** + * @brief ICU clock prescaler initialization utility. + * @note The real clock value is rounded to the lower valid value, please + * make sure that the source clock frequency is a multiple of the + * requested ICU clock frequency. + * @note The calculated value must fit into an unsigned 16 bits integer. + * + * @param[in] clksrc clock source frequency, depending on the target timer + * cell it can be one of: + * - STM32_TIMCLK1 + * - STM32_TIMCLK2 + * . + * Please refer to the STM32 HAL driver documentation + * and/or the STM32 Reference Manual for the right clock + * source. + * @param[in] icuclk ICU clock frequency in cycles + * @return The value to be stored in the @p psc field of the + * @p ICUConfig structure. + */ +#define ICU_COMPUTE_PSC(clksrc, icuclk) \ + ((uint16_t)(((clksrc) / (icuclk)) - 1)) + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if STM32_ICU_USE_TIM1 && !defined(__DOXYGEN__) +extern ICUDriver ICUD1; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + 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); + icucnt_t icu_lld_get_width(ICUDriver *icup); + icucnt_t icu_lld_get_period(ICUDriver *icup); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_ICU */ + +#endif /* _ICU_LLD_H_ */ + +/** @} */ diff --git a/os/hal/src/icu.c b/os/hal/src/icu.c new file mode 100644 index 000000000..3be67448e --- /dev/null +++ b/os/hal/src/icu.c @@ -0,0 +1,151 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file icu.c + * @brief ICU Driver code. + * + * @addtogroup ICU + * @{ + */ + +#include "ch.h" +#include "hal.h" + +#if HAL_USE_ICU || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief ICU Driver initialization. + * @note This function is implicitly invoked by @p halInit(), there is + * no need to explicitly initialize the driver. + * + * @init + */ +void icuInit(void) { + + icu_lld_init(); +} + +/** + * @brief Initializes the standard part of a @p ICUDriver structure. + * + * @param[out] icup pointer to the @p ICUDriver object + * + * @init + */ +void icuObjectInit(ICUDriver *icup) { + + icup->state = ICU_STOP; + icup->config = NULL; +} + +/** + * @brief Configures and activates the ICU peripheral. + * + * @param[in] icup pointer to the @p ICUDriver object + * @param[in] config pointer to the @p ICUConfig object + * + * @api + */ +void icuStart(ICUDriver *icup, const ICUConfig *config) { + + chDbgCheck((icup != NULL) && (config != NULL), "icuStart"); + + chSysLock(); + chDbgAssert((icup->state == ICU_STOP) || (icup->state == ICU_READY), + "icuStart(), #1", "invalid state"); + icup->config = config; + icu_lld_start(icup); + icup->state = ICU_READY; + chSysUnlock(); +} + +/** + * @brief Deactivates the ICU peripheral. + * + * @param[in] icup pointer to the @p ICUDriver object + * + * @api + */ +void icuStop(ICUDriver *icup) { + + chDbgCheck(icup != NULL, "icuStop"); + + chSysLock(); + chDbgAssert((icup->state == ICU_STOP) || (icup->state == ICU_READY), + "icuStop(), #1", "invalid state"); + icu_lld_stop(icup); + icup->state = ICU_STOP; + chSysUnlock(); +} + +/** + * @brief Enables the input capture. + * + * @param[in] icup pointer to the @p ICUDriver object + * + * @api + */ +void icuEnable(ICUDriver *icup) { + + chSysLock(); + chDbgAssert(icup->state == ICU_READY, "icuEnable(), #1", "invalid state"); + icu_lld_enable(icup); + icup->state = ICU_WAITING; + chSysUnlock(); +} + +/** + * @brief Disables the input capture. + * + * @param[in] icup pointer to the @p ICUDriver object + * + * @api + */ +void icuDisable(ICUDriver *icup) { + + chSysLock(); + chDbgAssert((icup->state == ICU_READY) || (icup->state == ICU_WAITING) || + (icup->state == ICU_ACTIVE) || (icup->state == ICU_IDLE), + "icuDisable(), #1", "invalid state"); + icu_lld_disable(icup); + icup->state = ICU_READY; + chSysUnlock(); +} + +#endif /* HAL_USE_ICU */ + +/** @} */ diff --git a/os/hal/templates/icu_lld.c b/os/hal/templates/icu_lld.c new file mode 100644 index 000000000..3611c1baa --- /dev/null +++ b/os/hal/templates/icu_lld.c @@ -0,0 +1,145 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file templates/icu_lld.c + * @brief ICU Driver subsystem low level driver source template. + * + * @addtogroup ICU + * @{ + */ + +#include "ch.h" +#include "hal.h" + +#if HAL_USE_ICU || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level ICU driver initialization. + * + * @notapi + */ +void icu_lld_init(void) { + +} + +/** + * @brief Configures and activates the ICU peripheral. + * + * @param[in] icup pointer to the @p ICUDriver object + * + * @notapi + */ +void icu_lld_start(ICUDriver *icup) { + + if (icup->state == ICU_STOP) { + /* Clock activation.*/ + } + /* Configuration.*/ +} + +/** + * @brief Deactivates the ICU peripheral. + * + * @param[in] icup pointer to the @p ICUDriver object + * + * @notapi + */ +void icu_lld_stop(ICUDriver *icup) { + + if (icup->state == ICU_READY) { + /* Clock deactivation.*/ + + } +} + +/** + * @brief Enables the input capture. + * + * @param[in] icup pointer to the @p ICUDriver object + * + * @notapi + */ +void icu_lld_enable(ICUDriver *icup) { + +} + +/** + * @brief Disables the input capture. + * + * @param[in] icup pointer to the @p ICUDriver object + * + * @notapi + */ +void icu_lld_disable(ICUDriver *icup) { + +} + +/** + * @brief Returns the width of the latest pulse. + * @details The pulse width is defined as number of ticks between the start + * edge and the stop edge. + * + * @param[in] icup pointer to the @p ICUDriver object + * @return The number of ticks. + * + * @notapi + */ +icucnt_t icu_lld_get_width(icup) { + +} + +/** + * @brief Returns the width of the latest cycle. + * @details The cycle width is defined as number of ticks between a start + * edge and the next start edge. + * + * @param[in] icup pointer to the @p ICUDriver object + * @return The number of ticks. + * + * @notapi + */ +icucnt_t icu_lld_get_period(icup) { + +} + +#endif /* HAL_USE_ICU */ + +/** @} */ diff --git a/os/hal/templates/icu_lld.h b/os/hal/templates/icu_lld.h new file mode 100644 index 000000000..b0debb2b9 --- /dev/null +++ b/os/hal/templates/icu_lld.h @@ -0,0 +1,136 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file templates/icu_lld.h + * @brief ICU Driver subsystem low level driver header template. + * + * @addtogroup ICU + * @{ + */ + +#ifndef _ICU_LLD_H_ +#define _ICU_LLD_H_ + +#if HAL_USE_ICU || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief ICU driver mode. + */ +typedef enum { + ICU_INPUT_ACTIVE_HIGH = 0, /**< Trigger on rising edge. */ + ICU_INPUT_ACTIVE_LOW = 1, /**< Trigger on falling edge. */ +} icumode_t; + +/** + * @brief ICU counter type. + */ +typedef uint16_t icucnt_t; + +/** + * @brief Type of a structure representing an ICU driver. + */ +typedef struct ICUDriver ICUDriver; + +/** + * @brief ICU notification callback type. + * + * @param[in] icup pointer to a @p ICUDriver object + */ +typedef void (*icucallback_t)(ICUDriver *icup); + +/** + * @brief Driver configuration structure. + * @note It could be empty on some architectures. + */ +typedef struct { + /** + * @brief Driver mode. + */ + icumode_t mode; + /** + * @brief Callback for pulse width measurement. + */ + icucallback_t width_cb; + /** + * @brief Callback for cycle period measurement. + */ + icucallback_t period_cb; + /* End of the mandatory fields.*/ +} ICUConfig; + +/** + * @brief Structure representing an ICU driver. + */ +struct ICUDriver { + /** + * @brief Driver state. + */ + icustate_t state; + /** + * @brief Current configuration data. + */ + const ICUConfig *config; + /* End of the mandatory fields.*/ +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + 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); + icucnt_t icu_lld_get_width(ICUDriver *icup); + icucnt_t icu_lld_get_period(ICUDriver *icup); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_ICU */ + +#endif /* _ICU_LLD_H_ */ + +/** @} */ diff --git a/readme.txt b/readme.txt index cbe419915..8cfda4619 100644 --- a/readme.txt +++ b/readme.txt @@ -79,6 +79,8 @@ - FIX: Fixed wrong checks in I/O Queues (bug 3219197)(backported to 2.2.3). - FIX: Fixed invalid assertion in adcConvert() (bug 3205410)(backported to 2.2.3). +- NEW: Added new ICU driver model, Input Capture Unit.. +- NEW: ICU driver implementation for STM32. - NEW: Implemented stack checking in the Cortex-Mx RVCT port (backported to 2.2.3). - NEW: Added support for PLL3 in STM32 HAL driver. Note, the format of the -- cgit v1.2.3