git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2848 35acf78f-673a-0410-8e92-d51de3d6d3f4

master
gdisirio 2011-03-28 15:32:56 +00:00
parent 6e6c6944fb
commit ff676aee33
17 changed files with 1162 additions and 27 deletions

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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.<br>
* 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.<br>
* 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
*/

View File

@ -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.
*

115
os/hal/dox/icu.dox Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
/**
* @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:
* - <b>ICU_INPUT_ACTIVE_HIGH</b>, a rising edge is the start signal.
* - <b>ICU_INPUT_ACTIVE_LOW</b>, a falling edge is the start signal.
* .
* After the activation the ICU unit can be in one of the following
* states at any time:
* - <b>ICU_WAITING</b>, waiting the first start signal.
* - <b>ICU_ACTIVE</b>, after a start signal.
* - <b>ICU_IDLE</b>, after a stop signal.
* .
* Callbacks are invoked when start or stop signals occur.
*
* @ingroup IO
*/

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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.

View File

@ -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.
*

131
os/hal/include/icu.h Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
/**
* @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_ */
/** @} */

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
/**
* @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 */
/** @} */

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
/**
* @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_ */
/** @} */

151
os/hal/src/icu.c Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
/**
* @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 */
/** @} */

145
os/hal/templates/icu_lld.c Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
/**
* @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 */
/** @} */

136
os/hal/templates/icu_lld.h Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
/**
* @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_ */
/** @} */

View File

@ -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