aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/src
diff options
context:
space:
mode:
Diffstat (limited to 'os/hal/src')
-rw-r--r--os/hal/src/ext.c59
1 files changed, 51 insertions, 8 deletions
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 */
/** @} */