From a840a0d418a1ca695412b934637b81f7e38cfef8 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 12 Aug 2013 16:13:20 +0000 Subject: [PATCH] Ported EXT. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6142 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- demos/ARMCM4-STM32F303-DISCOVERY/halconf.h | 2 +- os/hal/hal.mk | 1 + os/hal/include/ext.h | 154 ++++++++++++++++ os/hal/include/hal.h | 2 +- os/hal/platforms/STM32/ext_lld.c | 1 - os/hal/platforms/STM32F30x/ext_lld_isr.c | 136 ++++++-------- os/hal/src/ext.c | 204 +++++++++++++++++++++ 7 files changed, 421 insertions(+), 79 deletions(-) create mode 100644 os/hal/include/ext.h create mode 100644 os/hal/src/ext.c diff --git a/demos/ARMCM4-STM32F303-DISCOVERY/halconf.h b/demos/ARMCM4-STM32F303-DISCOVERY/halconf.h index 73aad1e62..6e6b0d0c9 100644 --- a/demos/ARMCM4-STM32F303-DISCOVERY/halconf.h +++ b/demos/ARMCM4-STM32F303-DISCOVERY/halconf.h @@ -55,7 +55,7 @@ * @brief Enables the EXT subsystem. */ #if !defined(HAL_USE_EXT) || defined(__DOXYGEN__) -#define HAL_USE_EXT FALSE +#define HAL_USE_EXT TRUE #endif /** diff --git a/os/hal/hal.mk b/os/hal/hal.mk index 5c2f6df75..9bccee1e1 100644 --- a/os/hal/hal.mk +++ b/os/hal/hal.mk @@ -4,6 +4,7 @@ HALSRC = ${CHIBIOS}/os/hal/src/hal.c \ ${CHIBIOS}/os/hal/src/hal_queues.c \ ${CHIBIOS}/os/hal/src/adc.c \ ${CHIBIOS}/os/hal/src/can.c \ + ${CHIBIOS}/os/hal/src/ext.c \ ${CHIBIOS}/os/hal/src/gpt.c \ ${CHIBIOS}/os/hal/src/icu.c \ ${CHIBIOS}/os/hal/src/pal.c \ diff --git a/os/hal/include/ext.h b/os/hal/include/ext.h new file mode 100644 index 000000000..89dc59df8 --- /dev/null +++ b/os/hal/include/ext.h @@ -0,0 +1,154 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012,2013 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 ext.h + * @brief EXT Driver macros and structures. + * + * @addtogroup EXT + * @{ + */ + +#ifndef _EXT_H_ +#define _EXT_H_ + +#if HAL_USE_EXT || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name EXT channel modes + * @{ + */ +#define EXT_CH_MODE_EDGES_MASK 3 /**< @brief Mask of edges field. */ +#define EXT_CH_MODE_DISABLED 0 /**< @brief Channel disabled. */ +#define EXT_CH_MODE_RISING_EDGE 1 /**< @brief Rising edge callback. */ +#define EXT_CH_MODE_FALLING_EDGE 2 /**< @brief Falling edge callback. */ +#define EXT_CH_MODE_BOTH_EDGES 3 /**< @brief Both edges callback. */ + +#define EXT_CH_MODE_AUTOSTART 4 /**< @brief Channel started + automatically on driver start. */ +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Driver state machine possible states. + */ +typedef enum { + EXT_UNINIT = 0, /**< Not initialized. */ + EXT_STOP = 1, /**< Stopped. */ + EXT_ACTIVE = 2, /**< Active. */ +} extstate_t; + +/** + * @brief Type of a structure representing a EXT driver. + */ +typedef struct EXTDriver EXTDriver; + +#include "ext_lld.h" + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @name Macro Functions + * @{ + */ +/** + * @brief Enables an EXT channel. + * + * @param[in] extp pointer to the @p EXTDriver object + * @param[in] channel channel to be enabled + * + * @iclass + */ +#define extChannelEnableI(extp, channel) ext_lld_channel_enable(extp, channel) + +/** + * @brief Disables an EXT channel. + * + * @param[in] extp pointer to the @p EXTDriver object + * @param[in] channel channel to be disabled + * + * @iclass + */ +#define extChannelDisableI(extp, channel) ext_lld_channel_disable(extp, channel) + +/** + * @brief Changes the operation mode of a channel. + * @note This function attempts to write over the current configuration + * structure that must have been not declared constant. This + * violates the @p const qualifier in @p extStart() but it is + * intentional. This function cannot be used if the configuration + * structure is declared @p const. + * + * @param[in] extp pointer to the @p EXTDriver object + * @param[in] channel channel to be changed + * @param[in] extcp new configuration for the channel + * + * @api + */ +#define extSetChannelMode(extp, channel, extcp) { \ + osalSysLock(); \ + extSetChannelModeI(extp, channel, extcp); \ + osalSysUnlock(); \ +} + +/** @} */ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void extInit(void); + void extObjectInit(EXTDriver *extp); + void extStart(EXTDriver *extp, const EXTConfig *config); + void extStop(EXTDriver *extp); + void extChannelEnable(EXTDriver *extp, expchannel_t channel); + void extChannelDisable(EXTDriver *extp, expchannel_t channel); + void extSetChannelModeI(EXTDriver *extp, + expchannel_t channel, + const EXTChannelConfig *extcp); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_EXT */ + +#endif /* _EXT_H_ */ + +/** @} */ diff --git a/os/hal/include/hal.h b/os/hal/include/hal.h index 883bf310f..81cf25571 100644 --- a/os/hal/include/hal.h +++ b/os/hal/include/hal.h @@ -48,7 +48,7 @@ #include "pal.h" #include "adc.h" #include "can.h" -//#include "ext.h" +#include "ext.h" #include "gpt.h" //#include "i2c.h" #include "icu.h" diff --git a/os/hal/platforms/STM32/ext_lld.c b/os/hal/platforms/STM32/ext_lld.c index 970e0ce8e..80b222124 100644 --- a/os/hal/platforms/STM32/ext_lld.c +++ b/os/hal/platforms/STM32/ext_lld.c @@ -22,7 +22,6 @@ * @{ */ -#include "ch.h" #include "hal.h" #if HAL_USE_EXT || defined(__DOXYGEN__) diff --git a/os/hal/platforms/STM32F30x/ext_lld_isr.c b/os/hal/platforms/STM32F30x/ext_lld_isr.c index c9802713e..08af37b19 100644 --- a/os/hal/platforms/STM32F30x/ext_lld_isr.c +++ b/os/hal/platforms/STM32F30x/ext_lld_isr.c @@ -22,7 +22,6 @@ * @{ */ -#include "ch.h" #include "hal.h" #if HAL_USE_EXT || defined(__DOXYGEN__) @@ -55,14 +54,14 @@ * * @isr */ -CH_IRQ_HANDLER(Vector58) { +OSAL_IRQ_HANDLER(Vector58) { - CH_IRQ_PROLOGUE(); + OSAL_IRQ_PROLOGUE(); EXTI->PR = (1 << 0); EXTD1.config->channels[0].cb(&EXTD1, 0); - CH_IRQ_EPILOGUE(); + OSAL_IRQ_EPILOGUE(); } #endif @@ -72,14 +71,14 @@ CH_IRQ_HANDLER(Vector58) { * * @isr */ -CH_IRQ_HANDLER(Vector5C) { +OSAL_IRQ_HANDLER(Vector5C) { - CH_IRQ_PROLOGUE(); + OSAL_IRQ_PROLOGUE(); EXTI->PR = (1 << 1); EXTD1.config->channels[1].cb(&EXTD1, 1); - CH_IRQ_EPILOGUE(); + OSAL_IRQ_EPILOGUE(); } #endif @@ -89,14 +88,14 @@ CH_IRQ_HANDLER(Vector5C) { * * @isr */ -CH_IRQ_HANDLER(Vector60) { +OSAL_IRQ_HANDLER(Vector60) { - CH_IRQ_PROLOGUE(); + OSAL_IRQ_PROLOGUE(); EXTI->PR = (1 << 2); EXTD1.config->channels[2].cb(&EXTD1, 2); - CH_IRQ_EPILOGUE(); + OSAL_IRQ_EPILOGUE(); } #endif @@ -106,14 +105,14 @@ CH_IRQ_HANDLER(Vector60) { * * @isr */ -CH_IRQ_HANDLER(Vector64) { +OSAL_IRQ_HANDLER(Vector64) { - CH_IRQ_PROLOGUE(); + OSAL_IRQ_PROLOGUE(); EXTI->PR = (1 << 3); EXTD1.config->channels[3].cb(&EXTD1, 3); - CH_IRQ_EPILOGUE(); + OSAL_IRQ_EPILOGUE(); } #endif @@ -123,14 +122,14 @@ CH_IRQ_HANDLER(Vector64) { * * @isr */ -CH_IRQ_HANDLER(Vector68) { +OSAL_IRQ_HANDLER(Vector68) { - CH_IRQ_PROLOGUE(); + OSAL_IRQ_PROLOGUE(); EXTI->PR = (1 << 4); EXTD1.config->channels[4].cb(&EXTD1, 4); - CH_IRQ_EPILOGUE(); + OSAL_IRQ_EPILOGUE(); } #endif @@ -140,10 +139,10 @@ CH_IRQ_HANDLER(Vector68) { * * @isr */ -CH_IRQ_HANDLER(Vector9C) { +OSAL_IRQ_HANDLER(Vector9C) { uint32_t pr; - CH_IRQ_PROLOGUE(); + OSAL_IRQ_PROLOGUE(); pr = EXTI->PR & ((1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 9)); EXTI->PR = pr; @@ -158,7 +157,7 @@ CH_IRQ_HANDLER(Vector9C) { if (pr & (1 << 9)) EXTD1.config->channels[9].cb(&EXTD1, 9); - CH_IRQ_EPILOGUE(); + OSAL_IRQ_EPILOGUE(); } #endif @@ -168,10 +167,10 @@ CH_IRQ_HANDLER(Vector9C) { * * @isr */ -CH_IRQ_HANDLER(VectorE0) { +OSAL_IRQ_HANDLER(VectorE0) { uint32_t pr; - CH_IRQ_PROLOGUE(); + OSAL_IRQ_PROLOGUE(); pr = EXTI->PR & ((1 << 10) | (1 << 11) | (1 << 12) | (1 << 13) | (1 << 14) | (1 << 15)); @@ -189,7 +188,7 @@ CH_IRQ_HANDLER(VectorE0) { if (pr & (1 << 15)) EXTD1.config->channels[15].cb(&EXTD1, 15); - CH_IRQ_EPILOGUE(); + OSAL_IRQ_EPILOGUE(); } #endif @@ -199,14 +198,14 @@ CH_IRQ_HANDLER(VectorE0) { * * @isr */ -CH_IRQ_HANDLER(Vector44) { +OSAL_IRQ_HANDLER(Vector44) { - CH_IRQ_PROLOGUE(); + OSAL_IRQ_PROLOGUE(); EXTI->PR = (1 << 16); EXTD1.config->channels[16].cb(&EXTD1, 16); - CH_IRQ_EPILOGUE(); + OSAL_IRQ_EPILOGUE(); } #endif @@ -216,14 +215,14 @@ CH_IRQ_HANDLER(Vector44) { * * @isr */ -CH_IRQ_HANDLER(VectorE4) { +OSAL_IRQ_HANDLER(VectorE4) { - CH_IRQ_PROLOGUE(); + OSAL_IRQ_PROLOGUE(); EXTI->PR = (1 << 17); EXTD1.config->channels[17].cb(&EXTD1, 17); - CH_IRQ_EPILOGUE(); + OSAL_IRQ_EPILOGUE(); } #endif @@ -233,14 +232,14 @@ CH_IRQ_HANDLER(VectorE4) { * * @isr */ -CH_IRQ_HANDLER(VectorE8) { +OSAL_IRQ_HANDLER(VectorE8) { - CH_IRQ_PROLOGUE(); + OSAL_IRQ_PROLOGUE(); EXTI->PR = (1 << 18); EXTD1.config->channels[18].cb(&EXTD1, 18); - CH_IRQ_EPILOGUE(); + OSAL_IRQ_EPILOGUE(); } #endif @@ -250,14 +249,14 @@ CH_IRQ_HANDLER(VectorE8) { * * @isr */ -CH_IRQ_HANDLER(Vector48) { +OSAL_IRQ_HANDLER(Vector48) { - CH_IRQ_PROLOGUE(); + OSAL_IRQ_PROLOGUE(); EXTI->PR = (1 << 19); EXTD1.config->channels[19].cb(&EXTD1, 19); - CH_IRQ_EPILOGUE(); + OSAL_IRQ_EPILOGUE(); } #endif @@ -267,14 +266,14 @@ CH_IRQ_HANDLER(Vector48) { * * @isr */ -CH_IRQ_HANDLER(Vector4C) { +OSAL_IRQ_HANDLER(Vector4C) { - CH_IRQ_PROLOGUE(); + OSAL_IRQ_PROLOGUE(); EXTI->PR = (1 << 20); EXTD1.config->channels[20].cb(&EXTD1, 20); - CH_IRQ_EPILOGUE(); + OSAL_IRQ_EPILOGUE(); } #endif @@ -284,10 +283,10 @@ CH_IRQ_HANDLER(Vector4C) { * * @isr */ -CH_IRQ_HANDLER(Vector140) { +OSAL_IRQ_HANDLER(Vector140) { uint32_t pr; - CH_IRQ_PROLOGUE(); + OSAL_IRQ_PROLOGUE(); pr = EXTI->PR & ((1 << 21) | (1 << 22) | (1 << 29)); EXTI->PR = pr; @@ -298,7 +297,7 @@ CH_IRQ_HANDLER(Vector140) { if (pr & (1 << 29)) EXTD1.config->channels[29].cb(&EXTD1, 29); - CH_IRQ_EPILOGUE(); + OSAL_IRQ_EPILOGUE(); } #endif @@ -308,10 +307,10 @@ CH_IRQ_HANDLER(Vector140) { * * @isr */ -CH_IRQ_HANDLER(Vector144) { +OSAL_IRQ_HANDLER(Vector144) { uint32_t pr; - CH_IRQ_PROLOGUE(); + OSAL_IRQ_PROLOGUE(); pr = EXTI->PR & ((1 << 30) | (1 << 31)); EXTI->PR = pr; @@ -325,7 +324,7 @@ CH_IRQ_HANDLER(Vector144) { if (pr & (1 << 0)) EXTD1.config->channels[32].cb(&EXTD1, 32); - CH_IRQ_EPILOGUE(); + OSAL_IRQ_EPILOGUE(); } #endif @@ -335,14 +334,14 @@ CH_IRQ_HANDLER(Vector144) { * * @isr */ -CH_IRQ_HANDLER(RTC_WKUP_IRQHandler) { +OSAL_IRQ_HANDLER(RTC_WKUP_IRQHandler) { - CH_IRQ_PROLOGUE(); + OSAL_IRQ_PROLOGUE(); EXTI->PR2 = (1 << 1); EXTD1.config->channels[33].cb(&EXTD1, 33); - CH_IRQ_EPILOGUE(); + OSAL_IRQ_EPILOGUE(); } #endif @@ -357,36 +356,21 @@ CH_IRQ_HANDLER(RTC_WKUP_IRQHandler) { */ void ext_lld_exti_irq_enable(void) { - nvicEnableVector(EXTI0_IRQn, - CORTEX_PRIORITY_MASK(STM32_EXT_EXTI0_IRQ_PRIORITY)); - nvicEnableVector(EXTI1_IRQn, - CORTEX_PRIORITY_MASK(STM32_EXT_EXTI1_IRQ_PRIORITY)); - nvicEnableVector(EXTI2_TS_IRQn, - CORTEX_PRIORITY_MASK(STM32_EXT_EXTI2_IRQ_PRIORITY)); - nvicEnableVector(EXTI3_IRQn, - CORTEX_PRIORITY_MASK(STM32_EXT_EXTI3_IRQ_PRIORITY)); - nvicEnableVector(EXTI4_IRQn, - CORTEX_PRIORITY_MASK(STM32_EXT_EXTI4_IRQ_PRIORITY)); - nvicEnableVector(EXTI9_5_IRQn, - CORTEX_PRIORITY_MASK(STM32_EXT_EXTI5_9_IRQ_PRIORITY)); - nvicEnableVector(EXTI15_10_IRQn, - CORTEX_PRIORITY_MASK(STM32_EXT_EXTI10_15_IRQ_PRIORITY)); - nvicEnableVector(PVD_IRQn, - CORTEX_PRIORITY_MASK(STM32_EXT_EXTI16_IRQ_PRIORITY)); - nvicEnableVector(RTC_Alarm_IRQn, - CORTEX_PRIORITY_MASK(STM32_EXT_EXTI17_IRQ_PRIORITY)); - nvicEnableVector(USBWakeUp_IRQn, - CORTEX_PRIORITY_MASK(STM32_EXT_EXTI18_IRQ_PRIORITY)); - nvicEnableVector(TAMPER_STAMP_IRQn, - CORTEX_PRIORITY_MASK(STM32_EXT_EXTI19_IRQ_PRIORITY)); - nvicEnableVector(RTC_WKUP_IRQn, - CORTEX_PRIORITY_MASK(STM32_EXT_EXTI20_IRQ_PRIORITY)); - nvicEnableVector(COMP1_2_3_IRQn, - CORTEX_PRIORITY_MASK(STM32_EXT_EXTI21_22_29_IRQ_PRIORITY)); - nvicEnableVector(COMP4_5_6_IRQn, - CORTEX_PRIORITY_MASK(STM32_EXT_EXTI30_32_IRQ_PRIORITY)); - nvicEnableVector(COMP7_IRQn, - CORTEX_PRIORITY_MASK(STM32_EXT_EXTI33_IRQ_PRIORITY)); + nvicEnableVector(EXTI0_IRQn, STM32_EXT_EXTI0_IRQ_PRIORITY); + nvicEnableVector(EXTI1_IRQn, STM32_EXT_EXTI1_IRQ_PRIORITY); + nvicEnableVector(EXTI2_TS_IRQn, STM32_EXT_EXTI2_IRQ_PRIORITY); + nvicEnableVector(EXTI3_IRQn, STM32_EXT_EXTI3_IRQ_PRIORITY); + nvicEnableVector(EXTI4_IRQn, STM32_EXT_EXTI4_IRQ_PRIORITY); + nvicEnableVector(EXTI9_5_IRQn, STM32_EXT_EXTI5_9_IRQ_PRIORITY); + nvicEnableVector(EXTI15_10_IRQn, STM32_EXT_EXTI10_15_IRQ_PRIORITY); + nvicEnableVector(PVD_IRQn, STM32_EXT_EXTI16_IRQ_PRIORITY); + nvicEnableVector(RTC_Alarm_IRQn, STM32_EXT_EXTI17_IRQ_PRIORITY); + nvicEnableVector(USBWakeUp_IRQn, STM32_EXT_EXTI18_IRQ_PRIORITY); + nvicEnableVector(TAMPER_STAMP_IRQn, STM32_EXT_EXTI19_IRQ_PRIORITY); + nvicEnableVector(RTC_WKUP_IRQn, STM32_EXT_EXTI20_IRQ_PRIORITY); + nvicEnableVector(COMP1_2_3_IRQn, STM32_EXT_EXTI21_22_29_IRQ_PRIORITY); + nvicEnableVector(COMP4_5_6_IRQn, STM32_EXT_EXTI30_32_IRQ_PRIORITY); + nvicEnableVector(COMP7_IRQn, STM32_EXT_EXTI33_IRQ_PRIORITY); } /** diff --git a/os/hal/src/ext.c b/os/hal/src/ext.c new file mode 100644 index 000000000..81c92525a --- /dev/null +++ b/os/hal/src/ext.c @@ -0,0 +1,204 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012,2013 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 ext.c + * @brief EXT Driver code. + * + * @addtogroup EXT + * @{ + */ + +#include "hal.h" + +#if HAL_USE_EXT || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief EXT Driver initialization. + * @note This function is implicitly invoked by @p halInit(), there is + * no need to explicitly initialize the driver. + * + * @init + */ +void extInit(void) { + + ext_lld_init(); +} + +/** + * @brief Initializes the standard part of a @p EXTDriver structure. + * + * @param[out] extp pointer to the @p EXTDriver object + * + * @init + */ +void extObjectInit(EXTDriver *extp) { + + extp->state = EXT_STOP; + extp->config = NULL; +} + +/** + * @brief Configures and activates the EXT peripheral. + * @post After activation all EXT channels are in the disabled state, + * use @p extChannelEnable() in order to activate them. + * + * @param[in] extp pointer to the @p EXTDriver object + * @param[in] config pointer to the @p EXTConfig object + * + * @api + */ +void extStart(EXTDriver *extp, const EXTConfig *config) { + + osalDbgCheck((extp != NULL) && (config != NULL)); + + osalSysLock(); + osalDbgAssert((extp->state == EXT_STOP) || (extp->state == EXT_ACTIVE), + "invalid state"); + extp->config = config; + ext_lld_start(extp); + extp->state = EXT_ACTIVE; + osalSysUnlock(); +} + +/** + * @brief Deactivates the EXT peripheral. + * + * @param[in] extp pointer to the @p EXTDriver object + * + * @api + */ +void extStop(EXTDriver *extp) { + + osalDbgCheck(extp != NULL); + + osalSysLock(); + osalDbgAssert((extp->state == EXT_STOP) || (extp->state == EXT_ACTIVE), + "invalid state"); + ext_lld_stop(extp); + extp->state = EXT_STOP; + osalSysUnlock(); +} + +/** + * @brief Enables an EXT channel. + * @pre The channel must not be in @p EXT_CH_MODE_DISABLED mode. + * + * @param[in] extp pointer to the @p EXTDriver object + * @param[in] channel channel to be enabled + * + * @api + */ +void extChannelEnable(EXTDriver *extp, expchannel_t channel) { + + osalDbgCheck((extp != NULL) && (channel < EXT_MAX_CHANNELS)); + + osalSysLock(); + osalDbgAssert((extp->state == EXT_ACTIVE) && + ((extp->config->channels[channel].mode & + EXT_CH_MODE_EDGES_MASK) != EXT_CH_MODE_DISABLED), + "invalid state"); + extChannelEnableI(extp, channel); + osalSysUnlock(); +} + +/** + * @brief Disables an EXT channel. + * @pre The channel must not be in @p EXT_CH_MODE_DISABLED mode. + * + * @param[in] extp pointer to the @p EXTDriver object + * @param[in] channel channel to be disabled + * + * @api + */ +void extChannelDisable(EXTDriver *extp, expchannel_t channel) { + + osalDbgCheck((extp != NULL) && (channel < EXT_MAX_CHANNELS)); + + osalSysLock(); + osalDbgAssert((extp->state == EXT_ACTIVE) && + ((extp->config->channels[channel].mode & + EXT_CH_MODE_EDGES_MASK) != EXT_CH_MODE_DISABLED), + "invalid state"); + extChannelDisableI(extp, channel); + osalSysUnlock(); +} + +/** + * @brief Changes the operation mode of a channel. + * @note This function attempts to write over the current configuration + * structure that must have been not declared constant. This + * violates the @p const qualifier in @p extStart() but it is + * intentional. + * @note This function cannot be used if the configuration structure is + * declared @p const. + * @note The effect of this function on constant configuration structures + * is not defined. + * + * @param[in] extp pointer to the @p EXTDriver object + * @param[in] channel channel to be changed + * @param[in] extcp new configuration for the channel + * + * @iclass + */ +void extSetChannelModeI(EXTDriver *extp, + expchannel_t channel, + const EXTChannelConfig *extcp) { + EXTChannelConfig *oldcp; + + osalDbgCheck((extp != NULL) && + (channel < EXT_MAX_CHANNELS) && + (extcp != NULL)); + + osalDbgAssert(extp->state == EXT_ACTIVE, "invalid state"); + + /* Note that here the access is enforced as non-const, known access + violation.*/ + oldcp = (EXTChannelConfig *)&extp->config->channels[channel]; + + /* Overwiting the old channels configuration then the channel is reconfigured + by the low level driver.*/ + *oldcp = *extcp; + ext_lld_channel_enable(extp, channel); +} + +#endif /* HAL_USE_EXT */ + +/** @} */