Mouse code for the MacroRat

Dependencies:   ITG3200 QEI

Committer:
sahilmgandhi
Date:
Sun May 14 23:18:57 2017 +0000
Revision:
18:6a4db94011d3
Publishing again

Who changed what in which revision?

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