mbed library sources. Supersedes mbed-src.

Fork of mbed-dev by mbed official

Committer:
mbed_official
Date:
Mon Nov 09 13:30:11 2015 +0000
Revision:
18:da299f395b9e
Parent:
targets/hal/TARGET_Atmel/TARGET_SAM_CortexM0P/drivers/extint/extint_sam_d_r/extint.c@15:a81a8d6c1dfe
Synchronized with git revision f605825f66bb2e462ff7dbc5fb4ed2dbe979d1c3

Full URL: https://github.com/mbedmicro/mbed/commit/f605825f66bb2e462ff7dbc5fb4ed2dbe979d1c3/

Added support for SAML21

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 15:a81a8d6c1dfe 1 /**
mbed_official 15:a81a8d6c1dfe 2 * \file
mbed_official 15:a81a8d6c1dfe 3 *
mbed_official 15:a81a8d6c1dfe 4 * \brief SAM External Interrupt Driver
mbed_official 15:a81a8d6c1dfe 5 *
mbed_official 15:a81a8d6c1dfe 6 * Copyright (C) 2012-2015 Atmel Corporation. All rights reserved.
mbed_official 15:a81a8d6c1dfe 7 *
mbed_official 15:a81a8d6c1dfe 8 * \asf_license_start
mbed_official 15:a81a8d6c1dfe 9 *
mbed_official 15:a81a8d6c1dfe 10 * \page License
mbed_official 15:a81a8d6c1dfe 11 *
mbed_official 15:a81a8d6c1dfe 12 * Redistribution and use in source and binary forms, with or without
mbed_official 15:a81a8d6c1dfe 13 * modification, are permitted provided that the following conditions are met:
mbed_official 15:a81a8d6c1dfe 14 *
mbed_official 15:a81a8d6c1dfe 15 * 1. Redistributions of source code must retain the above copyright notice,
mbed_official 15:a81a8d6c1dfe 16 * this list of conditions and the following disclaimer.
mbed_official 15:a81a8d6c1dfe 17 *
mbed_official 15:a81a8d6c1dfe 18 * 2. Redistributions in binary form must reproduce the above copyright notice,
mbed_official 15:a81a8d6c1dfe 19 * this list of conditions and the following disclaimer in the documentation
mbed_official 15:a81a8d6c1dfe 20 * and/or other materials provided with the distribution.
mbed_official 15:a81a8d6c1dfe 21 *
mbed_official 15:a81a8d6c1dfe 22 * 3. The name of Atmel may not be used to endorse or promote products derived
mbed_official 15:a81a8d6c1dfe 23 * from this software without specific prior written permission.
mbed_official 15:a81a8d6c1dfe 24 *
mbed_official 15:a81a8d6c1dfe 25 * 4. This software may only be redistributed and used in connection with an
mbed_official 15:a81a8d6c1dfe 26 * Atmel microcontroller product.
mbed_official 15:a81a8d6c1dfe 27 *
mbed_official 15:a81a8d6c1dfe 28 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
mbed_official 15:a81a8d6c1dfe 29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
mbed_official 15:a81a8d6c1dfe 30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
mbed_official 15:a81a8d6c1dfe 31 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
mbed_official 15:a81a8d6c1dfe 32 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
mbed_official 15:a81a8d6c1dfe 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
mbed_official 15:a81a8d6c1dfe 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
mbed_official 15:a81a8d6c1dfe 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
mbed_official 15:a81a8d6c1dfe 36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
mbed_official 15:a81a8d6c1dfe 37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
mbed_official 15:a81a8d6c1dfe 38 * POSSIBILITY OF SUCH DAMAGE.
mbed_official 15:a81a8d6c1dfe 39 *
mbed_official 15:a81a8d6c1dfe 40 * \asf_license_stop
mbed_official 15:a81a8d6c1dfe 41 *
mbed_official 15:a81a8d6c1dfe 42 */
mbed_official 15:a81a8d6c1dfe 43 /*
mbed_official 15:a81a8d6c1dfe 44 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
mbed_official 15:a81a8d6c1dfe 45 */
mbed_official 15:a81a8d6c1dfe 46 #include <system.h>
mbed_official 15:a81a8d6c1dfe 47 #include <system_interrupt.h>
mbed_official 15:a81a8d6c1dfe 48 #include <extint.h>
mbed_official 15:a81a8d6c1dfe 49 #include <conf_extint.h>
mbed_official 15:a81a8d6c1dfe 50
mbed_official 15:a81a8d6c1dfe 51 #if !defined(EXTINT_CLOCK_SOURCE) || defined(__DOXYGEN__)
mbed_official 15:a81a8d6c1dfe 52 # warning EXTINT_CLOCK_SOURCE is not defined, assuming GCLK_GENERATOR_0.
mbed_official 15:a81a8d6c1dfe 53
mbed_official 15:a81a8d6c1dfe 54 /** Configuration option, setting the EIC clock source which can be used for
mbed_official 15:a81a8d6c1dfe 55 * EIC edge detection or filtering. This option may be overridden in the module
mbed_official 15:a81a8d6c1dfe 56 * configuration header file \c conf_extint.h.
mbed_official 15:a81a8d6c1dfe 57 */
mbed_official 15:a81a8d6c1dfe 58 # define EXTINT_CLOCK_SOURCE GCLK_GENERATOR_0
mbed_official 15:a81a8d6c1dfe 59 #endif
mbed_official 15:a81a8d6c1dfe 60
mbed_official 15:a81a8d6c1dfe 61 /**
mbed_official 15:a81a8d6c1dfe 62 * \internal
mbed_official 15:a81a8d6c1dfe 63 * Internal driver device instance struct.
mbed_official 15:a81a8d6c1dfe 64 */
mbed_official 15:a81a8d6c1dfe 65 struct _extint_module _extint_dev;
mbed_official 15:a81a8d6c1dfe 66
mbed_official 15:a81a8d6c1dfe 67 /**
mbed_official 15:a81a8d6c1dfe 68 * \brief Determin if the general clock is required
mbed_official 15:a81a8d6c1dfe 69 *
mbed_official 15:a81a8d6c1dfe 70 * \param[in] filter_input_signal Filter the raw input signal to prevent noise
mbed_official 15:a81a8d6c1dfe 71 * \param[in] detection_criteria Edge detection mode to use (\ref extint_detect)
mbed_official 15:a81a8d6c1dfe 72 */
mbed_official 15:a81a8d6c1dfe 73 #define _extint_is_gclk_required(filter_input_signal, detection_criteria) \
mbed_official 15:a81a8d6c1dfe 74 ((filter_input_signal) ? true : (\
mbed_official 15:a81a8d6c1dfe 75 (EXTINT_DETECT_RISING == (detection_criteria)) ? true : (\
mbed_official 15:a81a8d6c1dfe 76 (EXTINT_DETECT_FALLING == (detection_criteria)) ? true : (\
mbed_official 15:a81a8d6c1dfe 77 (EXTINT_DETECT_BOTH == (detection_criteria)) ? true : false))))
mbed_official 15:a81a8d6c1dfe 78
mbed_official 15:a81a8d6c1dfe 79 static void _extint_enable(void);
mbed_official 15:a81a8d6c1dfe 80 static void _extint_disable(void);
mbed_official 15:a81a8d6c1dfe 81
mbed_official 15:a81a8d6c1dfe 82 /**
mbed_official 15:a81a8d6c1dfe 83 * \brief Determines if the hardware module(s) are currently synchronizing to the bus.
mbed_official 15:a81a8d6c1dfe 84 *
mbed_official 15:a81a8d6c1dfe 85 * Checks to see if the underlying hardware peripheral module(s) are currently
mbed_official 15:a81a8d6c1dfe 86 * synchronizing across multiple clock domains to the hardware bus, This
mbed_official 15:a81a8d6c1dfe 87 * function can be used to delay further operations on a module until such time
mbed_official 15:a81a8d6c1dfe 88 * that it is ready, to prevent blocking delays for synchronization in the
mbed_official 15:a81a8d6c1dfe 89 * user application.
mbed_official 15:a81a8d6c1dfe 90 *
mbed_official 15:a81a8d6c1dfe 91 * \return Synchronization status of the underlying hardware module(s).
mbed_official 15:a81a8d6c1dfe 92 *
mbed_official 15:a81a8d6c1dfe 93 * \retval true If the module synchronization is ongoing
mbed_official 15:a81a8d6c1dfe 94 * \retval false If the module has completed synchronization
mbed_official 15:a81a8d6c1dfe 95 */
mbed_official 15:a81a8d6c1dfe 96 static inline bool extint_is_syncing(void)
mbed_official 15:a81a8d6c1dfe 97 {
mbed_official 15:a81a8d6c1dfe 98 Eic *const eics[EIC_INST_NUM] = EIC_INSTS;
mbed_official 15:a81a8d6c1dfe 99
mbed_official 15:a81a8d6c1dfe 100 for (uint32_t i = 0; i < EIC_INST_NUM; i++) {
mbed_official 15:a81a8d6c1dfe 101 if (eics[i]->STATUS.reg & EIC_STATUS_SYNCBUSY) {
mbed_official 15:a81a8d6c1dfe 102 return true;
mbed_official 15:a81a8d6c1dfe 103 }
mbed_official 15:a81a8d6c1dfe 104 }
mbed_official 15:a81a8d6c1dfe 105 return false;
mbed_official 15:a81a8d6c1dfe 106 }
mbed_official 15:a81a8d6c1dfe 107 /**
mbed_official 15:a81a8d6c1dfe 108 * \internal
mbed_official 15:a81a8d6c1dfe 109 * \brief Initializes and enables the External Interrupt driver.
mbed_official 15:a81a8d6c1dfe 110 *
mbed_official 15:a81a8d6c1dfe 111 * Enable the clocks used by External Interrupt driver.
mbed_official 15:a81a8d6c1dfe 112 *
mbed_official 15:a81a8d6c1dfe 113 * Resets the External Interrupt driver, resetting all hardware
mbed_official 15:a81a8d6c1dfe 114 * module registers to their power-on defaults, then enable it for further use.
mbed_official 15:a81a8d6c1dfe 115 *
mbed_official 15:a81a8d6c1dfe 116 * Reset the callback list if callback mode is used.
mbed_official 15:a81a8d6c1dfe 117 *
mbed_official 15:a81a8d6c1dfe 118 * This function must be called before attempting to use any NMI or standard
mbed_official 15:a81a8d6c1dfe 119 * external interrupt channel functions.
mbed_official 15:a81a8d6c1dfe 120 *
mbed_official 15:a81a8d6c1dfe 121 * \note When SYSTEM module is used, this function will be invoked by
mbed_official 15:a81a8d6c1dfe 122 * \ref system_init() automatically if the module is included.
mbed_official 15:a81a8d6c1dfe 123 */
mbed_official 15:a81a8d6c1dfe 124 void _system_extint_init(void);
mbed_official 15:a81a8d6c1dfe 125 void _system_extint_init(void)
mbed_official 15:a81a8d6c1dfe 126 {
mbed_official 15:a81a8d6c1dfe 127 Eic *const eics[EIC_INST_NUM] = EIC_INSTS;
mbed_official 15:a81a8d6c1dfe 128
mbed_official 15:a81a8d6c1dfe 129 /* Turn on the digital interface clock */
mbed_official 15:a81a8d6c1dfe 130 system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBA, PM_APBAMASK_EIC);
mbed_official 15:a81a8d6c1dfe 131
mbed_official 15:a81a8d6c1dfe 132 /* Configure the generic clock for the module and enable it */
mbed_official 15:a81a8d6c1dfe 133 struct system_gclk_chan_config gclk_chan_conf;
mbed_official 15:a81a8d6c1dfe 134 system_gclk_chan_get_config_defaults(&gclk_chan_conf);
mbed_official 15:a81a8d6c1dfe 135 gclk_chan_conf.source_generator = EXTINT_CLOCK_SOURCE;
mbed_official 15:a81a8d6c1dfe 136 system_gclk_chan_set_config(EIC_GCLK_ID, &gclk_chan_conf);
mbed_official 15:a81a8d6c1dfe 137
mbed_official 15:a81a8d6c1dfe 138 /* Enable the clock anyway, since when needed it will be requested
mbed_official 15:a81a8d6c1dfe 139 * by External Interrupt driver */
mbed_official 15:a81a8d6c1dfe 140 system_gclk_chan_enable(EIC_GCLK_ID);
mbed_official 15:a81a8d6c1dfe 141
mbed_official 15:a81a8d6c1dfe 142 /* Reset all EIC hardware modules. */
mbed_official 15:a81a8d6c1dfe 143 for (uint32_t i = 0; i < EIC_INST_NUM; i++) {
mbed_official 15:a81a8d6c1dfe 144 eics[i]->CTRL.reg |= EIC_CTRL_SWRST;
mbed_official 15:a81a8d6c1dfe 145 }
mbed_official 15:a81a8d6c1dfe 146
mbed_official 15:a81a8d6c1dfe 147 while (extint_is_syncing()) {
mbed_official 15:a81a8d6c1dfe 148 /* Wait for all hardware modules to complete synchronization */
mbed_official 15:a81a8d6c1dfe 149 }
mbed_official 15:a81a8d6c1dfe 150
mbed_official 15:a81a8d6c1dfe 151 /* Reset the software module */
mbed_official 15:a81a8d6c1dfe 152 #if EXTINT_CALLBACK_MODE == true
mbed_official 15:a81a8d6c1dfe 153 /* Clear callback registration table */
mbed_official 15:a81a8d6c1dfe 154 for (uint8_t j = 0; j < EIC_NUMBER_OF_INTERRUPTS; j++) {
mbed_official 15:a81a8d6c1dfe 155 _extint_dev.callbacks[j] = NULL;
mbed_official 15:a81a8d6c1dfe 156 }
mbed_official 15:a81a8d6c1dfe 157 system_interrupt_enable(SYSTEM_INTERRUPT_MODULE_EIC);
mbed_official 15:a81a8d6c1dfe 158 #endif
mbed_official 15:a81a8d6c1dfe 159
mbed_official 15:a81a8d6c1dfe 160 /* Enables the driver for further use */
mbed_official 15:a81a8d6c1dfe 161 _extint_enable();
mbed_official 15:a81a8d6c1dfe 162 }
mbed_official 15:a81a8d6c1dfe 163
mbed_official 15:a81a8d6c1dfe 164 /**
mbed_official 15:a81a8d6c1dfe 165 * \internal
mbed_official 15:a81a8d6c1dfe 166 * \brief Enables the External Interrupt driver.
mbed_official 15:a81a8d6c1dfe 167 *
mbed_official 15:a81a8d6c1dfe 168 * Enables EIC modules.
mbed_official 15:a81a8d6c1dfe 169 * Registered callback list will not be affected if callback mode is used.
mbed_official 15:a81a8d6c1dfe 170 */
mbed_official 15:a81a8d6c1dfe 171 void _extint_enable(void)
mbed_official 15:a81a8d6c1dfe 172 {
mbed_official 15:a81a8d6c1dfe 173 Eic *const eics[EIC_INST_NUM] = EIC_INSTS;
mbed_official 15:a81a8d6c1dfe 174
mbed_official 15:a81a8d6c1dfe 175 /* Enable all EIC hardware modules. */
mbed_official 15:a81a8d6c1dfe 176 for (uint32_t i = 0; i < EIC_INST_NUM; i++) {
mbed_official 15:a81a8d6c1dfe 177 eics[i]->CTRL.reg |= EIC_CTRL_ENABLE;
mbed_official 15:a81a8d6c1dfe 178 }
mbed_official 15:a81a8d6c1dfe 179
mbed_official 15:a81a8d6c1dfe 180 while (extint_is_syncing()) {
mbed_official 15:a81a8d6c1dfe 181 /* Wait for all hardware modules to complete synchronization */
mbed_official 15:a81a8d6c1dfe 182 }
mbed_official 15:a81a8d6c1dfe 183 }
mbed_official 15:a81a8d6c1dfe 184
mbed_official 15:a81a8d6c1dfe 185 /**
mbed_official 15:a81a8d6c1dfe 186 * \internal
mbed_official 15:a81a8d6c1dfe 187 * \brief Disables the External Interrupt driver.
mbed_official 15:a81a8d6c1dfe 188 *
mbed_official 15:a81a8d6c1dfe 189 * Disables EIC modules that were previously started via a call to
mbed_official 15:a81a8d6c1dfe 190 * \ref _extint_enable().
mbed_official 15:a81a8d6c1dfe 191 * Registered callback list will not be affected if callback mode is used.
mbed_official 15:a81a8d6c1dfe 192 */
mbed_official 15:a81a8d6c1dfe 193 void _extint_disable(void)
mbed_official 15:a81a8d6c1dfe 194 {
mbed_official 15:a81a8d6c1dfe 195 Eic *const eics[EIC_INST_NUM] = EIC_INSTS;
mbed_official 15:a81a8d6c1dfe 196
mbed_official 15:a81a8d6c1dfe 197 /* Disable all EIC hardware modules. */
mbed_official 15:a81a8d6c1dfe 198 for (uint32_t i = 0; i < EIC_INST_NUM; i++) {
mbed_official 15:a81a8d6c1dfe 199 eics[i]->CTRL.reg &= ~EIC_CTRL_ENABLE;
mbed_official 15:a81a8d6c1dfe 200 }
mbed_official 15:a81a8d6c1dfe 201
mbed_official 15:a81a8d6c1dfe 202 while (extint_is_syncing()) {
mbed_official 15:a81a8d6c1dfe 203 /* Wait for all hardware modules to complete synchronization */
mbed_official 15:a81a8d6c1dfe 204 }
mbed_official 15:a81a8d6c1dfe 205 }
mbed_official 15:a81a8d6c1dfe 206
mbed_official 15:a81a8d6c1dfe 207 /**
mbed_official 15:a81a8d6c1dfe 208 * \brief Initializes an External Interrupt channel configuration structure to defaults.
mbed_official 15:a81a8d6c1dfe 209 *
mbed_official 15:a81a8d6c1dfe 210 * Initializes a given External Interrupt channel configuration structure to a
mbed_official 15:a81a8d6c1dfe 211 * set of known default values. This function should be called on all new
mbed_official 15:a81a8d6c1dfe 212 * instances of these configuration structures before being modified by the
mbed_official 15:a81a8d6c1dfe 213 * user application.
mbed_official 15:a81a8d6c1dfe 214 *
mbed_official 15:a81a8d6c1dfe 215 * The default configuration is as follows:
mbed_official 15:a81a8d6c1dfe 216 * \li Wake the device if an edge detection occurs whilst in sleep
mbed_official 15:a81a8d6c1dfe 217 * \li Input filtering disabled
mbed_official 15:a81a8d6c1dfe 218 * \li Internal pull-up enabled
mbed_official 15:a81a8d6c1dfe 219 * \li Detect falling edges of a signal
mbed_official 15:a81a8d6c1dfe 220 *
mbed_official 15:a81a8d6c1dfe 221 * \param[out] config Configuration structure to initialize to default values
mbed_official 15:a81a8d6c1dfe 222 */
mbed_official 15:a81a8d6c1dfe 223 void extint_chan_get_config_defaults(
mbed_official 15:a81a8d6c1dfe 224 struct extint_chan_conf *const config)
mbed_official 15:a81a8d6c1dfe 225 {
mbed_official 15:a81a8d6c1dfe 226 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 227 Assert(config);
mbed_official 15:a81a8d6c1dfe 228
mbed_official 15:a81a8d6c1dfe 229 /* Default configuration values */
mbed_official 15:a81a8d6c1dfe 230 config->gpio_pin = 0;
mbed_official 15:a81a8d6c1dfe 231 config->gpio_pin_mux = 0;
mbed_official 15:a81a8d6c1dfe 232 config->gpio_pin_pull = EXTINT_PULL_UP;
mbed_official 15:a81a8d6c1dfe 233 config->wake_if_sleeping = true;
mbed_official 15:a81a8d6c1dfe 234 config->filter_input_signal = false;
mbed_official 15:a81a8d6c1dfe 235 config->detection_criteria = EXTINT_DETECT_FALLING;
mbed_official 15:a81a8d6c1dfe 236 }
mbed_official 15:a81a8d6c1dfe 237
mbed_official 15:a81a8d6c1dfe 238 /**
mbed_official 15:a81a8d6c1dfe 239 * \brief Writes an External Interrupt channel configuration to the hardware module.
mbed_official 15:a81a8d6c1dfe 240 *
mbed_official 15:a81a8d6c1dfe 241 * Writes out a given configuration of an External Interrupt channel
mbed_official 15:a81a8d6c1dfe 242 * configuration to the hardware module. If the channel is already configured,
mbed_official 15:a81a8d6c1dfe 243 * the new configuration will replace the existing one.
mbed_official 15:a81a8d6c1dfe 244 *
mbed_official 15:a81a8d6c1dfe 245 * \param[in] channel External Interrupt channel to configure
mbed_official 15:a81a8d6c1dfe 246 * \param[in] config Configuration settings for the channel
mbed_official 15:a81a8d6c1dfe 247
mbed_official 15:a81a8d6c1dfe 248 */
mbed_official 15:a81a8d6c1dfe 249 void extint_chan_set_config(
mbed_official 15:a81a8d6c1dfe 250 const uint8_t channel,
mbed_official 15:a81a8d6c1dfe 251 const struct extint_chan_conf *const config)
mbed_official 15:a81a8d6c1dfe 252 {
mbed_official 15:a81a8d6c1dfe 253 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 254 Assert(config);
mbed_official 15:a81a8d6c1dfe 255 /* Sanity check clock requirements */
mbed_official 15:a81a8d6c1dfe 256 Assert(!(!system_gclk_gen_is_enabled(EXTINT_CLOCK_SOURCE) &&
mbed_official 15:a81a8d6c1dfe 257 _extint_is_gclk_required(config->filter_input_signal,
mbed_official 15:a81a8d6c1dfe 258 config->detection_criteria)));
mbed_official 15:a81a8d6c1dfe 259
mbed_official 15:a81a8d6c1dfe 260 struct system_pinmux_config pinmux_config;
mbed_official 15:a81a8d6c1dfe 261 system_pinmux_get_config_defaults(&pinmux_config);
mbed_official 15:a81a8d6c1dfe 262
mbed_official 15:a81a8d6c1dfe 263 pinmux_config.mux_position = config->gpio_pin_mux;
mbed_official 15:a81a8d6c1dfe 264 pinmux_config.direction = SYSTEM_PINMUX_PIN_DIR_INPUT;
mbed_official 15:a81a8d6c1dfe 265 pinmux_config.input_pull = (enum system_pinmux_pin_pull)config->gpio_pin_pull;
mbed_official 15:a81a8d6c1dfe 266 system_pinmux_pin_set_config(config->gpio_pin, &pinmux_config);
mbed_official 15:a81a8d6c1dfe 267
mbed_official 15:a81a8d6c1dfe 268 /* Get a pointer to the module hardware instance */
mbed_official 15:a81a8d6c1dfe 269 Eic *const EIC_module = _extint_get_eic_from_channel(channel);
mbed_official 15:a81a8d6c1dfe 270
mbed_official 15:a81a8d6c1dfe 271 uint32_t config_pos = (4 * (channel % 8));
mbed_official 15:a81a8d6c1dfe 272 uint32_t new_config;
mbed_official 15:a81a8d6c1dfe 273
mbed_official 15:a81a8d6c1dfe 274 /* Determine the channel's new edge detection configuration */
mbed_official 15:a81a8d6c1dfe 275 new_config = (config->detection_criteria << EIC_CONFIG_SENSE0_Pos);
mbed_official 15:a81a8d6c1dfe 276
mbed_official 15:a81a8d6c1dfe 277 /* Enable the hardware signal filter if requested in the config */
mbed_official 15:a81a8d6c1dfe 278 if (config->filter_input_signal) {
mbed_official 15:a81a8d6c1dfe 279 new_config |= EIC_CONFIG_FILTEN0;
mbed_official 15:a81a8d6c1dfe 280 }
mbed_official 15:a81a8d6c1dfe 281
mbed_official 15:a81a8d6c1dfe 282 /* Clear the existing and set the new channel configuration */
mbed_official 15:a81a8d6c1dfe 283 EIC_module->CONFIG[channel / 8].reg
mbed_official 15:a81a8d6c1dfe 284 = (EIC_module->CONFIG[channel / 8].reg &
mbed_official 15:a81a8d6c1dfe 285 ~((EIC_CONFIG_SENSE0_Msk | EIC_CONFIG_FILTEN0) << config_pos)) |
mbed_official 15:a81a8d6c1dfe 286 (new_config << config_pos);
mbed_official 15:a81a8d6c1dfe 287
mbed_official 15:a81a8d6c1dfe 288 /* Set the channel's new wake up mode setting */
mbed_official 15:a81a8d6c1dfe 289 if (config->wake_if_sleeping) {
mbed_official 15:a81a8d6c1dfe 290 EIC_module->WAKEUP.reg |= (1UL << channel);
mbed_official 15:a81a8d6c1dfe 291 } else {
mbed_official 15:a81a8d6c1dfe 292 EIC_module->WAKEUP.reg &= ~(1UL << channel);
mbed_official 15:a81a8d6c1dfe 293 }
mbed_official 15:a81a8d6c1dfe 294 }
mbed_official 15:a81a8d6c1dfe 295
mbed_official 15:a81a8d6c1dfe 296 /**
mbed_official 15:a81a8d6c1dfe 297 * \brief Writes an External Interrupt NMI channel configuration to the hardware module.
mbed_official 15:a81a8d6c1dfe 298 *
mbed_official 15:a81a8d6c1dfe 299 * Writes out a given configuration of an External Interrupt NMI channel
mbed_official 15:a81a8d6c1dfe 300 * configuration to the hardware module. If the channel is already configured,
mbed_official 15:a81a8d6c1dfe 301 * the new configuration will replace the existing one.
mbed_official 15:a81a8d6c1dfe 302 *
mbed_official 15:a81a8d6c1dfe 303 * \param[in] nmi_channel External Interrupt NMI channel to configure
mbed_official 15:a81a8d6c1dfe 304 * \param[in] config Configuration settings for the channel
mbed_official 15:a81a8d6c1dfe 305 *
mbed_official 15:a81a8d6c1dfe 306 * \returns Status code indicating the success or failure of the request.
mbed_official 15:a81a8d6c1dfe 307 * \retval STATUS_OK Configuration succeeded
mbed_official 15:a81a8d6c1dfe 308 * \retval STATUS_ERR_PIN_MUX_INVALID An invalid pinmux value was supplied
mbed_official 15:a81a8d6c1dfe 309 * \retval STATUS_ERR_BAD_FORMAT An invalid detection mode was requested
mbed_official 15:a81a8d6c1dfe 310 */
mbed_official 15:a81a8d6c1dfe 311 enum status_code extint_nmi_set_config(
mbed_official 15:a81a8d6c1dfe 312 const uint8_t nmi_channel,
mbed_official 15:a81a8d6c1dfe 313 const struct extint_nmi_conf *const config)
mbed_official 15:a81a8d6c1dfe 314 {
mbed_official 15:a81a8d6c1dfe 315 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 316 Assert(config);
mbed_official 15:a81a8d6c1dfe 317 /* Sanity check clock requirements */
mbed_official 15:a81a8d6c1dfe 318 Assert(!(!system_gclk_gen_is_enabled(EXTINT_CLOCK_SOURCE) &&
mbed_official 15:a81a8d6c1dfe 319 _extint_is_gclk_required(config->filter_input_signal,
mbed_official 15:a81a8d6c1dfe 320 config->detection_criteria)));
mbed_official 15:a81a8d6c1dfe 321
mbed_official 15:a81a8d6c1dfe 322 struct system_pinmux_config pinmux_config;
mbed_official 15:a81a8d6c1dfe 323 system_pinmux_get_config_defaults(&pinmux_config);
mbed_official 15:a81a8d6c1dfe 324
mbed_official 15:a81a8d6c1dfe 325 pinmux_config.mux_position = config->gpio_pin_mux;
mbed_official 15:a81a8d6c1dfe 326 pinmux_config.direction = SYSTEM_PINMUX_PIN_DIR_INPUT;
mbed_official 15:a81a8d6c1dfe 327 pinmux_config.input_pull = SYSTEM_PINMUX_PIN_PULL_UP;
mbed_official 15:a81a8d6c1dfe 328 pinmux_config.input_pull = (enum system_pinmux_pin_pull)config->gpio_pin_pull;
mbed_official 15:a81a8d6c1dfe 329 system_pinmux_pin_set_config(config->gpio_pin, &pinmux_config);
mbed_official 15:a81a8d6c1dfe 330
mbed_official 15:a81a8d6c1dfe 331 /* Get a pointer to the module hardware instance */
mbed_official 15:a81a8d6c1dfe 332 Eic *const EIC_module = _extint_get_eic_from_channel(nmi_channel);
mbed_official 15:a81a8d6c1dfe 333
mbed_official 15:a81a8d6c1dfe 334 uint32_t new_config;
mbed_official 15:a81a8d6c1dfe 335
mbed_official 15:a81a8d6c1dfe 336 /* Determine the NMI's new edge detection configuration */
mbed_official 15:a81a8d6c1dfe 337 new_config = (config->detection_criteria << EIC_NMICTRL_NMISENSE_Pos);
mbed_official 15:a81a8d6c1dfe 338
mbed_official 15:a81a8d6c1dfe 339 /* Enable the hardware signal filter if requested in the config */
mbed_official 15:a81a8d6c1dfe 340 if (config->filter_input_signal) {
mbed_official 15:a81a8d6c1dfe 341 new_config |= EIC_NMICTRL_NMIFILTEN;
mbed_official 15:a81a8d6c1dfe 342 }
mbed_official 15:a81a8d6c1dfe 343
mbed_official 15:a81a8d6c1dfe 344 /* Disable EIC and general clock to configure NMI */
mbed_official 15:a81a8d6c1dfe 345 _extint_disable();
mbed_official 15:a81a8d6c1dfe 346 system_gclk_chan_disable(EIC_GCLK_ID);
mbed_official 15:a81a8d6c1dfe 347
mbed_official 15:a81a8d6c1dfe 348 EIC_module->NMICTRL.reg = new_config;
mbed_official 15:a81a8d6c1dfe 349
mbed_official 15:a81a8d6c1dfe 350 /* Enable the general clock and EIC after configure NMI */
mbed_official 15:a81a8d6c1dfe 351 system_gclk_chan_enable(EIC_GCLK_ID);
mbed_official 15:a81a8d6c1dfe 352 _extint_enable();
mbed_official 15:a81a8d6c1dfe 353
mbed_official 15:a81a8d6c1dfe 354 return STATUS_OK;
mbed_official 15:a81a8d6c1dfe 355 }
mbed_official 15:a81a8d6c1dfe 356
mbed_official 15:a81a8d6c1dfe 357 /**
mbed_official 15:a81a8d6c1dfe 358 * \brief Enables an External Interrupt event output.
mbed_official 15:a81a8d6c1dfe 359 *
mbed_official 15:a81a8d6c1dfe 360 * Enables one or more output events from the External Interrupt module. See
mbed_official 15:a81a8d6c1dfe 361 * \ref extint_events "here" for a list of events this module supports.
mbed_official 15:a81a8d6c1dfe 362 *
mbed_official 15:a81a8d6c1dfe 363 * \note Events cannot be altered while the module is enabled.
mbed_official 15:a81a8d6c1dfe 364 *
mbed_official 15:a81a8d6c1dfe 365 * \param[in] events Struct containing flags of events to enable
mbed_official 15:a81a8d6c1dfe 366 */
mbed_official 15:a81a8d6c1dfe 367 void extint_enable_events(
mbed_official 15:a81a8d6c1dfe 368 struct extint_events *const events)
mbed_official 15:a81a8d6c1dfe 369 {
mbed_official 15:a81a8d6c1dfe 370 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 371 Assert(events);
mbed_official 15:a81a8d6c1dfe 372
mbed_official 15:a81a8d6c1dfe 373 /* Array of available EICs. */
mbed_official 15:a81a8d6c1dfe 374 Eic *const eics[EIC_INST_NUM] = EIC_INSTS;
mbed_official 15:a81a8d6c1dfe 375
mbed_official 15:a81a8d6c1dfe 376 /* Update the event control register for each physical EIC instance */
mbed_official 15:a81a8d6c1dfe 377 for (uint32_t i = 0; i < EIC_INST_NUM; i++) {
mbed_official 15:a81a8d6c1dfe 378 uint32_t event_mask = 0;
mbed_official 15:a81a8d6c1dfe 379
mbed_official 15:a81a8d6c1dfe 380 /* Create an enable mask for the current EIC module */
mbed_official 15:a81a8d6c1dfe 381 for (uint32_t j = 0; j < 32; j++) {
mbed_official 15:a81a8d6c1dfe 382 if (events->generate_event_on_detect[(32 * i) + j]) {
mbed_official 15:a81a8d6c1dfe 383 event_mask |= (1UL << j);
mbed_official 15:a81a8d6c1dfe 384 }
mbed_official 15:a81a8d6c1dfe 385 }
mbed_official 15:a81a8d6c1dfe 386
mbed_official 15:a81a8d6c1dfe 387 /* Enable the masked events */
mbed_official 15:a81a8d6c1dfe 388 eics[i]->EVCTRL.reg |= event_mask;
mbed_official 15:a81a8d6c1dfe 389 }
mbed_official 15:a81a8d6c1dfe 390 }
mbed_official 15:a81a8d6c1dfe 391
mbed_official 15:a81a8d6c1dfe 392 /**
mbed_official 15:a81a8d6c1dfe 393 * \brief Disables an External Interrupt event output.
mbed_official 15:a81a8d6c1dfe 394 *
mbed_official 15:a81a8d6c1dfe 395 * Disables one or more output events from the External Interrupt module. See
mbed_official 15:a81a8d6c1dfe 396 * \ref extint_events "here" for a list of events this module supports.
mbed_official 15:a81a8d6c1dfe 397 *
mbed_official 15:a81a8d6c1dfe 398 * \note Events cannot be altered while the module is enabled.
mbed_official 15:a81a8d6c1dfe 399 *
mbed_official 15:a81a8d6c1dfe 400 * \param[in] events Struct containing flags of events to disable
mbed_official 15:a81a8d6c1dfe 401 */
mbed_official 15:a81a8d6c1dfe 402 void extint_disable_events(
mbed_official 15:a81a8d6c1dfe 403 struct extint_events *const events)
mbed_official 15:a81a8d6c1dfe 404 {
mbed_official 15:a81a8d6c1dfe 405 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 406 Assert(events);
mbed_official 15:a81a8d6c1dfe 407
mbed_official 15:a81a8d6c1dfe 408 /* Array of available EICs. */
mbed_official 15:a81a8d6c1dfe 409 Eic *const eics[EIC_INST_NUM] = EIC_INSTS;
mbed_official 15:a81a8d6c1dfe 410
mbed_official 15:a81a8d6c1dfe 411 /* Update the event control register for each physical EIC instance */
mbed_official 15:a81a8d6c1dfe 412 for (uint32_t i = 0; i < EIC_INST_NUM; i++) {
mbed_official 15:a81a8d6c1dfe 413 uint32_t event_mask = 0;
mbed_official 15:a81a8d6c1dfe 414
mbed_official 15:a81a8d6c1dfe 415 /* Create a disable mask for the current EIC module */
mbed_official 15:a81a8d6c1dfe 416 for (uint32_t j = 0; j < 32; j++) {
mbed_official 15:a81a8d6c1dfe 417 if (events->generate_event_on_detect[(32 * i) + j]) {
mbed_official 15:a81a8d6c1dfe 418 event_mask |= (1UL << j);
mbed_official 15:a81a8d6c1dfe 419 }
mbed_official 15:a81a8d6c1dfe 420 }
mbed_official 15:a81a8d6c1dfe 421
mbed_official 15:a81a8d6c1dfe 422 /* Disable the masked events */
mbed_official 15:a81a8d6c1dfe 423 eics[i]->EVCTRL.reg &= ~event_mask;
mbed_official 15:a81a8d6c1dfe 424 }
mbed_official 15:a81a8d6c1dfe 425 }