From e817b7032d9610508e39921c65cda6ba108db357 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 23 Apr 2012 17:43:42 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4128 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/src/ext.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 8 deletions(-) (limited to 'os/hal/src') diff --git a/os/hal/src/ext.c b/os/hal/src/ext.c index e89962dea..bd175d483 100644 --- a/os/hal/src/ext.c +++ b/os/hal/src/ext.c @@ -120,6 +120,7 @@ void extStop(EXTDriver *extp) { /** * @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 @@ -128,13 +129,13 @@ void extStop(EXTDriver *extp) { */ void extChannelEnable(EXTDriver *extp, expchannel_t channel) { - chDbgCheck((extp != NULL) && - (channel < EXT_MAX_CHANNELS) && - (extp->config->channels[channel].mode != EXT_CH_MODE_DISABLED), + chDbgCheck((extp != NULL) && (channel < EXT_MAX_CHANNELS), "extChannelEnable"); chSysLock(); - chDbgAssert(extp->state == EXT_ACTIVE, + chDbgAssert((extp->state == EXT_ACTIVE) && + ((extp->config->channels[channel].mode & + EXT_CH_MODE_EDGES_MASK) != EXT_CH_MODE_DISABLED), "extChannelEnable(), #1", "invalid state"); extChannelEnableI(extp, channel); chSysUnlock(); @@ -142,6 +143,7 @@ void extChannelEnable(EXTDriver *extp, expchannel_t channel) { /** * @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 @@ -150,18 +152,59 @@ void extChannelEnable(EXTDriver *extp, expchannel_t channel) { */ void extChannelDisable(EXTDriver *extp, expchannel_t channel) { - chDbgCheck((extp != NULL) && - (channel < EXT_MAX_CHANNELS) && - (extp->config->channels[channel].mode != EXT_CH_MODE_DISABLED), + chDbgCheck((extp != NULL) && (channel < EXT_MAX_CHANNELS), "extChannelDisable"); chSysLock(); - chDbgAssert(extp->state == EXT_ACTIVE, + chDbgAssert((extp->state == EXT_ACTIVE) && + ((extp->config->channels[channel].mode & + EXT_CH_MODE_EDGES_MASK) != EXT_CH_MODE_DISABLED), "extChannelDisable(), #1", "invalid state"); extChannelDisableI(extp, channel); chSysUnlock(); } +/** + * @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; + + chDbgCheck((extp != NULL) && (channel < EXT_MAX_CHANNELS) && + (extcp != NULL), "extSetChannelModeI"); + + /* Note that here the access is enforced as non-const, known access + violation.*/ + oldcp = (EXTChannelConfig *)&extp->config->channels[channel]; + + chSysLock(); + + chDbgAssert(extp->state == EXT_ACTIVE, + "extSetChannelModeI(), #1", "invalid state"); + + /* Overwiting the old channels configuration then the channel is reconfigured + by the low level driver.*/ + *oldcp = *extcp; + ext_lld_channel_enable(extp, channel); + chSysUnlock(); +} + #endif /* HAL_USE_EXT */ /** @} */ -- cgit v1.2.3