mbed library sources. Supersedes mbed-src.

Fork of mbed-dev by mbed official

Committer:
screamer
Date:
Tue Aug 02 14:07:36 2016 +0000
Revision:
144:423e1876dc07
Parent:
18:da299f395b9e
Added targets.json file for the supported targets in the release

Who changed what in which revision?

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