Mouse code for the MacroRat

Dependencies:   ITG3200 QEI

Committer:
sahilmgandhi
Date:
Sat Jun 03 00:22:44 2017 +0000
Revision:
46:b156ef445742
Parent:
18:6a4db94011d3
Final code for internal battlebot competition.

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) 2012-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_SOURCE) || defined(__DOXYGEN__)
sahilmgandhi 18:6a4db94011d3 52 # warning EXTINT_CLOCK_SOURCE is not defined, assuming GCLK_GENERATOR_0.
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_SOURCE GCLK_GENERATOR_0
sahilmgandhi 18:6a4db94011d3 59 #endif
sahilmgandhi 18:6a4db94011d3 60
sahilmgandhi 18:6a4db94011d3 61 /**
sahilmgandhi 18:6a4db94011d3 62 * \internal
sahilmgandhi 18:6a4db94011d3 63 * Internal driver device instance struct.
sahilmgandhi 18:6a4db94011d3 64 */
sahilmgandhi 18:6a4db94011d3 65 struct _extint_module _extint_dev;
sahilmgandhi 18:6a4db94011d3 66
sahilmgandhi 18:6a4db94011d3 67 /**
sahilmgandhi 18:6a4db94011d3 68 * \brief Determin if the general clock is required
sahilmgandhi 18:6a4db94011d3 69 *
sahilmgandhi 18:6a4db94011d3 70 * \param[in] filter_input_signal Filter the raw input signal to prevent noise
sahilmgandhi 18:6a4db94011d3 71 * \param[in] detection_criteria Edge detection mode to use (\ref extint_detect)
sahilmgandhi 18:6a4db94011d3 72 */
sahilmgandhi 18:6a4db94011d3 73 #define _extint_is_gclk_required(filter_input_signal, detection_criteria) \
sahilmgandhi 18:6a4db94011d3 74 ((filter_input_signal) ? true : (\
sahilmgandhi 18:6a4db94011d3 75 (EXTINT_DETECT_RISING == (detection_criteria)) ? true : (\
sahilmgandhi 18:6a4db94011d3 76 (EXTINT_DETECT_FALLING == (detection_criteria)) ? true : (\
sahilmgandhi 18:6a4db94011d3 77 (EXTINT_DETECT_BOTH == (detection_criteria)) ? true : false))))
sahilmgandhi 18:6a4db94011d3 78
sahilmgandhi 18:6a4db94011d3 79 static void _extint_enable(void);
sahilmgandhi 18:6a4db94011d3 80 static void _extint_disable(void);
sahilmgandhi 18:6a4db94011d3 81
sahilmgandhi 18:6a4db94011d3 82 /**
sahilmgandhi 18:6a4db94011d3 83 * \brief Determines if the hardware module(s) are currently synchronizing to the bus.
sahilmgandhi 18:6a4db94011d3 84 *
sahilmgandhi 18:6a4db94011d3 85 * Checks to see if the underlying hardware peripheral module(s) are currently
sahilmgandhi 18:6a4db94011d3 86 * synchronizing across multiple clock domains to the hardware bus, This
sahilmgandhi 18:6a4db94011d3 87 * function can be used to delay further operations on a module until such time
sahilmgandhi 18:6a4db94011d3 88 * that it is ready, to prevent blocking delays for synchronization in the
sahilmgandhi 18:6a4db94011d3 89 * user application.
sahilmgandhi 18:6a4db94011d3 90 *
sahilmgandhi 18:6a4db94011d3 91 * \return Synchronization status of the underlying hardware module(s).
sahilmgandhi 18:6a4db94011d3 92 *
sahilmgandhi 18:6a4db94011d3 93 * \retval true If the module synchronization is ongoing
sahilmgandhi 18:6a4db94011d3 94 * \retval false If the module has completed synchronization
sahilmgandhi 18:6a4db94011d3 95 */
sahilmgandhi 18:6a4db94011d3 96 static inline bool extint_is_syncing(void)
sahilmgandhi 18:6a4db94011d3 97 {
sahilmgandhi 18:6a4db94011d3 98 Eic *const eics[EIC_INST_NUM] = EIC_INSTS;
sahilmgandhi 18:6a4db94011d3 99
sahilmgandhi 18:6a4db94011d3 100 for (uint32_t i = 0; i < EIC_INST_NUM; i++) {
sahilmgandhi 18:6a4db94011d3 101 if (eics[i]->STATUS.reg & EIC_STATUS_SYNCBUSY) {
sahilmgandhi 18:6a4db94011d3 102 return true;
sahilmgandhi 18:6a4db94011d3 103 }
sahilmgandhi 18:6a4db94011d3 104 }
sahilmgandhi 18:6a4db94011d3 105 return false;
sahilmgandhi 18:6a4db94011d3 106 }
sahilmgandhi 18:6a4db94011d3 107 /**
sahilmgandhi 18:6a4db94011d3 108 * \internal
sahilmgandhi 18:6a4db94011d3 109 * \brief Initializes and enables the External Interrupt driver.
sahilmgandhi 18:6a4db94011d3 110 *
sahilmgandhi 18:6a4db94011d3 111 * Enable the clocks used by External Interrupt driver.
sahilmgandhi 18:6a4db94011d3 112 *
sahilmgandhi 18:6a4db94011d3 113 * Resets the External Interrupt driver, resetting all hardware
sahilmgandhi 18:6a4db94011d3 114 * module registers to their power-on defaults, then enable it for further use.
sahilmgandhi 18:6a4db94011d3 115 *
sahilmgandhi 18:6a4db94011d3 116 * Reset the callback list if callback mode is used.
sahilmgandhi 18:6a4db94011d3 117 *
sahilmgandhi 18:6a4db94011d3 118 * This function must be called before attempting to use any NMI or standard
sahilmgandhi 18:6a4db94011d3 119 * external interrupt channel functions.
sahilmgandhi 18:6a4db94011d3 120 *
sahilmgandhi 18:6a4db94011d3 121 * \note When SYSTEM module is used, this function will be invoked by
sahilmgandhi 18:6a4db94011d3 122 * \ref system_init() automatically if the module is included.
sahilmgandhi 18:6a4db94011d3 123 */
sahilmgandhi 18:6a4db94011d3 124 void _system_extint_init(void);
sahilmgandhi 18:6a4db94011d3 125 void _system_extint_init(void)
sahilmgandhi 18:6a4db94011d3 126 {
sahilmgandhi 18:6a4db94011d3 127 Eic *const eics[EIC_INST_NUM] = EIC_INSTS;
sahilmgandhi 18:6a4db94011d3 128
sahilmgandhi 18:6a4db94011d3 129 /* Turn on the digital interface clock */
sahilmgandhi 18:6a4db94011d3 130 system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBA, PM_APBAMASK_EIC);
sahilmgandhi 18:6a4db94011d3 131
sahilmgandhi 18:6a4db94011d3 132 /* Configure the generic clock for the module and enable it */
sahilmgandhi 18:6a4db94011d3 133 struct system_gclk_chan_config gclk_chan_conf;
sahilmgandhi 18:6a4db94011d3 134 system_gclk_chan_get_config_defaults(&gclk_chan_conf);
sahilmgandhi 18:6a4db94011d3 135 gclk_chan_conf.source_generator = EXTINT_CLOCK_SOURCE;
sahilmgandhi 18:6a4db94011d3 136 system_gclk_chan_set_config(EIC_GCLK_ID, &gclk_chan_conf);
sahilmgandhi 18:6a4db94011d3 137
sahilmgandhi 18:6a4db94011d3 138 /* Enable the clock anyway, since when needed it will be requested
sahilmgandhi 18:6a4db94011d3 139 * by External Interrupt driver */
sahilmgandhi 18:6a4db94011d3 140 system_gclk_chan_enable(EIC_GCLK_ID);
sahilmgandhi 18:6a4db94011d3 141
sahilmgandhi 18:6a4db94011d3 142 /* Reset all EIC hardware modules. */
sahilmgandhi 18:6a4db94011d3 143 for (uint32_t i = 0; i < EIC_INST_NUM; i++) {
sahilmgandhi 18:6a4db94011d3 144 eics[i]->CTRL.reg |= EIC_CTRL_SWRST;
sahilmgandhi 18:6a4db94011d3 145 }
sahilmgandhi 18:6a4db94011d3 146
sahilmgandhi 18:6a4db94011d3 147 while (extint_is_syncing()) {
sahilmgandhi 18:6a4db94011d3 148 /* Wait for all hardware modules to complete synchronization */
sahilmgandhi 18:6a4db94011d3 149 }
sahilmgandhi 18:6a4db94011d3 150
sahilmgandhi 18:6a4db94011d3 151 /* Reset the software module */
sahilmgandhi 18:6a4db94011d3 152 #if EXTINT_CALLBACK_MODE == true
sahilmgandhi 18:6a4db94011d3 153 /* Clear callback registration table */
sahilmgandhi 18:6a4db94011d3 154 for (uint8_t j = 0; j < EIC_NUMBER_OF_INTERRUPTS; j++) {
sahilmgandhi 18:6a4db94011d3 155 _extint_dev.callbacks[j] = NULL;
sahilmgandhi 18:6a4db94011d3 156 }
sahilmgandhi 18:6a4db94011d3 157 system_interrupt_enable(SYSTEM_INTERRUPT_MODULE_EIC);
sahilmgandhi 18:6a4db94011d3 158 #endif
sahilmgandhi 18:6a4db94011d3 159
sahilmgandhi 18:6a4db94011d3 160 /* Enables the driver for further use */
sahilmgandhi 18:6a4db94011d3 161 _extint_enable();
sahilmgandhi 18:6a4db94011d3 162 }
sahilmgandhi 18:6a4db94011d3 163
sahilmgandhi 18:6a4db94011d3 164 /**
sahilmgandhi 18:6a4db94011d3 165 * \internal
sahilmgandhi 18:6a4db94011d3 166 * \brief Enables the External Interrupt driver.
sahilmgandhi 18:6a4db94011d3 167 *
sahilmgandhi 18:6a4db94011d3 168 * Enables EIC modules.
sahilmgandhi 18:6a4db94011d3 169 * Registered callback list will not be affected if callback mode is used.
sahilmgandhi 18:6a4db94011d3 170 */
sahilmgandhi 18:6a4db94011d3 171 void _extint_enable(void)
sahilmgandhi 18:6a4db94011d3 172 {
sahilmgandhi 18:6a4db94011d3 173 Eic *const eics[EIC_INST_NUM] = EIC_INSTS;
sahilmgandhi 18:6a4db94011d3 174
sahilmgandhi 18:6a4db94011d3 175 /* Enable all EIC hardware modules. */
sahilmgandhi 18:6a4db94011d3 176 for (uint32_t i = 0; i < EIC_INST_NUM; i++) {
sahilmgandhi 18:6a4db94011d3 177 eics[i]->CTRL.reg |= EIC_CTRL_ENABLE;
sahilmgandhi 18:6a4db94011d3 178 }
sahilmgandhi 18:6a4db94011d3 179
sahilmgandhi 18:6a4db94011d3 180 while (extint_is_syncing()) {
sahilmgandhi 18:6a4db94011d3 181 /* Wait for all hardware modules to complete synchronization */
sahilmgandhi 18:6a4db94011d3 182 }
sahilmgandhi 18:6a4db94011d3 183 }
sahilmgandhi 18:6a4db94011d3 184
sahilmgandhi 18:6a4db94011d3 185 /**
sahilmgandhi 18:6a4db94011d3 186 * \internal
sahilmgandhi 18:6a4db94011d3 187 * \brief Disables the External Interrupt driver.
sahilmgandhi 18:6a4db94011d3 188 *
sahilmgandhi 18:6a4db94011d3 189 * Disables EIC modules that were previously started via a call to
sahilmgandhi 18:6a4db94011d3 190 * \ref _extint_enable().
sahilmgandhi 18:6a4db94011d3 191 * Registered callback list will not be affected if callback mode is used.
sahilmgandhi 18:6a4db94011d3 192 */
sahilmgandhi 18:6a4db94011d3 193 void _extint_disable(void)
sahilmgandhi 18:6a4db94011d3 194 {
sahilmgandhi 18:6a4db94011d3 195 Eic *const eics[EIC_INST_NUM] = EIC_INSTS;
sahilmgandhi 18:6a4db94011d3 196
sahilmgandhi 18:6a4db94011d3 197 /* Disable all EIC hardware modules. */
sahilmgandhi 18:6a4db94011d3 198 for (uint32_t i = 0; i < EIC_INST_NUM; i++) {
sahilmgandhi 18:6a4db94011d3 199 eics[i]->CTRL.reg &= ~EIC_CTRL_ENABLE;
sahilmgandhi 18:6a4db94011d3 200 }
sahilmgandhi 18:6a4db94011d3 201
sahilmgandhi 18:6a4db94011d3 202 while (extint_is_syncing()) {
sahilmgandhi 18:6a4db94011d3 203 /* Wait for all hardware modules to complete synchronization */
sahilmgandhi 18:6a4db94011d3 204 }
sahilmgandhi 18:6a4db94011d3 205 }
sahilmgandhi 18:6a4db94011d3 206
sahilmgandhi 18:6a4db94011d3 207 /**
sahilmgandhi 18:6a4db94011d3 208 * \brief Initializes an External Interrupt channel configuration structure to defaults.
sahilmgandhi 18:6a4db94011d3 209 *
sahilmgandhi 18:6a4db94011d3 210 * Initializes a given External Interrupt channel configuration structure to a
sahilmgandhi 18:6a4db94011d3 211 * set of known default values. This function should be called on all new
sahilmgandhi 18:6a4db94011d3 212 * instances of these configuration structures before being modified by the
sahilmgandhi 18:6a4db94011d3 213 * user application.
sahilmgandhi 18:6a4db94011d3 214 *
sahilmgandhi 18:6a4db94011d3 215 * The default configuration is as follows:
sahilmgandhi 18:6a4db94011d3 216 * \li Wake the device if an edge detection occurs whilst in sleep
sahilmgandhi 18:6a4db94011d3 217 * \li Input filtering disabled
sahilmgandhi 18:6a4db94011d3 218 * \li Internal pull-up enabled
sahilmgandhi 18:6a4db94011d3 219 * \li Detect falling edges of a signal
sahilmgandhi 18:6a4db94011d3 220 *
sahilmgandhi 18:6a4db94011d3 221 * \param[out] config Configuration structure to initialize to default values
sahilmgandhi 18:6a4db94011d3 222 */
sahilmgandhi 18:6a4db94011d3 223 void extint_chan_get_config_defaults(
sahilmgandhi 18:6a4db94011d3 224 struct extint_chan_conf *const config)
sahilmgandhi 18:6a4db94011d3 225 {
sahilmgandhi 18:6a4db94011d3 226 /* Sanity check arguments */
sahilmgandhi 18:6a4db94011d3 227 Assert(config);
sahilmgandhi 18:6a4db94011d3 228
sahilmgandhi 18:6a4db94011d3 229 /* Default configuration values */
sahilmgandhi 18:6a4db94011d3 230 config->gpio_pin = 0;
sahilmgandhi 18:6a4db94011d3 231 config->gpio_pin_mux = 0;
sahilmgandhi 18:6a4db94011d3 232 config->gpio_pin_pull = EXTINT_PULL_UP;
sahilmgandhi 18:6a4db94011d3 233 config->wake_if_sleeping = true;
sahilmgandhi 18:6a4db94011d3 234 config->filter_input_signal = false;
sahilmgandhi 18:6a4db94011d3 235 config->detection_criteria = EXTINT_DETECT_FALLING;
sahilmgandhi 18:6a4db94011d3 236 }
sahilmgandhi 18:6a4db94011d3 237
sahilmgandhi 18:6a4db94011d3 238 /**
sahilmgandhi 18:6a4db94011d3 239 * \brief Writes an External Interrupt channel configuration to the hardware module.
sahilmgandhi 18:6a4db94011d3 240 *
sahilmgandhi 18:6a4db94011d3 241 * Writes out a given configuration of an External Interrupt channel
sahilmgandhi 18:6a4db94011d3 242 * configuration to the hardware module. If the channel is already configured,
sahilmgandhi 18:6a4db94011d3 243 * the new configuration will replace the existing one.
sahilmgandhi 18:6a4db94011d3 244 *
sahilmgandhi 18:6a4db94011d3 245 * \param[in] channel External Interrupt channel to configure
sahilmgandhi 18:6a4db94011d3 246 * \param[in] config Configuration settings for the channel
sahilmgandhi 18:6a4db94011d3 247
sahilmgandhi 18:6a4db94011d3 248 */
sahilmgandhi 18:6a4db94011d3 249 void extint_chan_set_config(
sahilmgandhi 18:6a4db94011d3 250 const uint8_t channel,
sahilmgandhi 18:6a4db94011d3 251 const struct extint_chan_conf *const config)
sahilmgandhi 18:6a4db94011d3 252 {
sahilmgandhi 18:6a4db94011d3 253 /* Sanity check arguments */
sahilmgandhi 18:6a4db94011d3 254 Assert(config);
sahilmgandhi 18:6a4db94011d3 255 /* Sanity check clock requirements */
sahilmgandhi 18:6a4db94011d3 256 Assert(!(!system_gclk_gen_is_enabled(EXTINT_CLOCK_SOURCE) &&
sahilmgandhi 18:6a4db94011d3 257 _extint_is_gclk_required(config->filter_input_signal,
sahilmgandhi 18:6a4db94011d3 258 config->detection_criteria)));
sahilmgandhi 18:6a4db94011d3 259
sahilmgandhi 18:6a4db94011d3 260 struct system_pinmux_config pinmux_config;
sahilmgandhi 18:6a4db94011d3 261 system_pinmux_get_config_defaults(&pinmux_config);
sahilmgandhi 18:6a4db94011d3 262
sahilmgandhi 18:6a4db94011d3 263 pinmux_config.mux_position = config->gpio_pin_mux;
sahilmgandhi 18:6a4db94011d3 264 pinmux_config.direction = SYSTEM_PINMUX_PIN_DIR_INPUT;
sahilmgandhi 18:6a4db94011d3 265 pinmux_config.input_pull = (enum system_pinmux_pin_pull)config->gpio_pin_pull;
sahilmgandhi 18:6a4db94011d3 266 system_pinmux_pin_set_config(config->gpio_pin, &pinmux_config);
sahilmgandhi 18:6a4db94011d3 267
sahilmgandhi 18:6a4db94011d3 268 /* Get a pointer to the module hardware instance */
sahilmgandhi 18:6a4db94011d3 269 Eic *const EIC_module = _extint_get_eic_from_channel(channel);
sahilmgandhi 18:6a4db94011d3 270
sahilmgandhi 18:6a4db94011d3 271 uint32_t config_pos = (4 * (channel % 8));
sahilmgandhi 18:6a4db94011d3 272 uint32_t new_config;
sahilmgandhi 18:6a4db94011d3 273
sahilmgandhi 18:6a4db94011d3 274 /* Determine the channel's new edge detection configuration */
sahilmgandhi 18:6a4db94011d3 275 new_config = (config->detection_criteria << EIC_CONFIG_SENSE0_Pos);
sahilmgandhi 18:6a4db94011d3 276
sahilmgandhi 18:6a4db94011d3 277 /* Enable the hardware signal filter if requested in the config */
sahilmgandhi 18:6a4db94011d3 278 if (config->filter_input_signal) {
sahilmgandhi 18:6a4db94011d3 279 new_config |= EIC_CONFIG_FILTEN0;
sahilmgandhi 18:6a4db94011d3 280 }
sahilmgandhi 18:6a4db94011d3 281
sahilmgandhi 18:6a4db94011d3 282 /* Clear the existing and set the new channel configuration */
sahilmgandhi 18:6a4db94011d3 283 EIC_module->CONFIG[channel / 8].reg
sahilmgandhi 18:6a4db94011d3 284 = (EIC_module->CONFIG[channel / 8].reg &
sahilmgandhi 18:6a4db94011d3 285 ~((EIC_CONFIG_SENSE0_Msk | EIC_CONFIG_FILTEN0) << config_pos)) |
sahilmgandhi 18:6a4db94011d3 286 (new_config << config_pos);
sahilmgandhi 18:6a4db94011d3 287
sahilmgandhi 18:6a4db94011d3 288 /* Set the channel's new wake up mode setting */
sahilmgandhi 18:6a4db94011d3 289 if (config->wake_if_sleeping) {
sahilmgandhi 18:6a4db94011d3 290 EIC_module->WAKEUP.reg |= (1UL << channel);
sahilmgandhi 18:6a4db94011d3 291 } else {
sahilmgandhi 18:6a4db94011d3 292 EIC_module->WAKEUP.reg &= ~(1UL << channel);
sahilmgandhi 18:6a4db94011d3 293 }
sahilmgandhi 18:6a4db94011d3 294 }
sahilmgandhi 18:6a4db94011d3 295
sahilmgandhi 18:6a4db94011d3 296 /**
sahilmgandhi 18:6a4db94011d3 297 * \brief Writes an External Interrupt NMI channel configuration to the hardware module.
sahilmgandhi 18:6a4db94011d3 298 *
sahilmgandhi 18:6a4db94011d3 299 * Writes out a given configuration of an External Interrupt NMI channel
sahilmgandhi 18:6a4db94011d3 300 * configuration to the hardware module. If the channel is already configured,
sahilmgandhi 18:6a4db94011d3 301 * the new configuration will replace the existing one.
sahilmgandhi 18:6a4db94011d3 302 *
sahilmgandhi 18:6a4db94011d3 303 * \param[in] nmi_channel External Interrupt NMI channel to configure
sahilmgandhi 18:6a4db94011d3 304 * \param[in] config Configuration settings for the channel
sahilmgandhi 18:6a4db94011d3 305 *
sahilmgandhi 18:6a4db94011d3 306 * \returns Status code indicating the success or failure of the request.
sahilmgandhi 18:6a4db94011d3 307 * \retval STATUS_OK Configuration succeeded
sahilmgandhi 18:6a4db94011d3 308 * \retval STATUS_ERR_PIN_MUX_INVALID An invalid pinmux value was supplied
sahilmgandhi 18:6a4db94011d3 309 * \retval STATUS_ERR_BAD_FORMAT An invalid detection mode was requested
sahilmgandhi 18:6a4db94011d3 310 */
sahilmgandhi 18:6a4db94011d3 311 enum status_code extint_nmi_set_config(
sahilmgandhi 18:6a4db94011d3 312 const uint8_t nmi_channel,
sahilmgandhi 18:6a4db94011d3 313 const struct extint_nmi_conf *const config)
sahilmgandhi 18:6a4db94011d3 314 {
sahilmgandhi 18:6a4db94011d3 315 /* Sanity check arguments */
sahilmgandhi 18:6a4db94011d3 316 Assert(config);
sahilmgandhi 18:6a4db94011d3 317 /* Sanity check clock requirements */
sahilmgandhi 18:6a4db94011d3 318 Assert(!(!system_gclk_gen_is_enabled(EXTINT_CLOCK_SOURCE) &&
sahilmgandhi 18:6a4db94011d3 319 _extint_is_gclk_required(config->filter_input_signal,
sahilmgandhi 18:6a4db94011d3 320 config->detection_criteria)));
sahilmgandhi 18:6a4db94011d3 321
sahilmgandhi 18:6a4db94011d3 322 struct system_pinmux_config pinmux_config;
sahilmgandhi 18:6a4db94011d3 323 system_pinmux_get_config_defaults(&pinmux_config);
sahilmgandhi 18:6a4db94011d3 324
sahilmgandhi 18:6a4db94011d3 325 pinmux_config.mux_position = config->gpio_pin_mux;
sahilmgandhi 18:6a4db94011d3 326 pinmux_config.direction = SYSTEM_PINMUX_PIN_DIR_INPUT;
sahilmgandhi 18:6a4db94011d3 327 pinmux_config.input_pull = SYSTEM_PINMUX_PIN_PULL_UP;
sahilmgandhi 18:6a4db94011d3 328 pinmux_config.input_pull = (enum system_pinmux_pin_pull)config->gpio_pin_pull;
sahilmgandhi 18:6a4db94011d3 329 system_pinmux_pin_set_config(config->gpio_pin, &pinmux_config);
sahilmgandhi 18:6a4db94011d3 330
sahilmgandhi 18:6a4db94011d3 331 /* Get a pointer to the module hardware instance */
sahilmgandhi 18:6a4db94011d3 332 Eic *const EIC_module = _extint_get_eic_from_channel(nmi_channel);
sahilmgandhi 18:6a4db94011d3 333
sahilmgandhi 18:6a4db94011d3 334 uint32_t new_config;
sahilmgandhi 18:6a4db94011d3 335
sahilmgandhi 18:6a4db94011d3 336 /* Determine the NMI's new edge detection configuration */
sahilmgandhi 18:6a4db94011d3 337 new_config = (config->detection_criteria << EIC_NMICTRL_NMISENSE_Pos);
sahilmgandhi 18:6a4db94011d3 338
sahilmgandhi 18:6a4db94011d3 339 /* Enable the hardware signal filter if requested in the config */
sahilmgandhi 18:6a4db94011d3 340 if (config->filter_input_signal) {
sahilmgandhi 18:6a4db94011d3 341 new_config |= EIC_NMICTRL_NMIFILTEN;
sahilmgandhi 18:6a4db94011d3 342 }
sahilmgandhi 18:6a4db94011d3 343
sahilmgandhi 18:6a4db94011d3 344 /* Disable EIC and general clock to configure NMI */
sahilmgandhi 18:6a4db94011d3 345 _extint_disable();
sahilmgandhi 18:6a4db94011d3 346 system_gclk_chan_disable(EIC_GCLK_ID);
sahilmgandhi 18:6a4db94011d3 347
sahilmgandhi 18:6a4db94011d3 348 EIC_module->NMICTRL.reg = new_config;
sahilmgandhi 18:6a4db94011d3 349
sahilmgandhi 18:6a4db94011d3 350 /* Enable the general clock and EIC after configure NMI */
sahilmgandhi 18:6a4db94011d3 351 system_gclk_chan_enable(EIC_GCLK_ID);
sahilmgandhi 18:6a4db94011d3 352 _extint_enable();
sahilmgandhi 18:6a4db94011d3 353
sahilmgandhi 18:6a4db94011d3 354 return STATUS_OK;
sahilmgandhi 18:6a4db94011d3 355 }
sahilmgandhi 18:6a4db94011d3 356
sahilmgandhi 18:6a4db94011d3 357 /**
sahilmgandhi 18:6a4db94011d3 358 * \brief Enables an External Interrupt event output.
sahilmgandhi 18:6a4db94011d3 359 *
sahilmgandhi 18:6a4db94011d3 360 * Enables one or more output events from the External Interrupt module. See
sahilmgandhi 18:6a4db94011d3 361 * \ref extint_events "here" for a list of events this module supports.
sahilmgandhi 18:6a4db94011d3 362 *
sahilmgandhi 18:6a4db94011d3 363 * \note Events cannot be altered while the module is enabled.
sahilmgandhi 18:6a4db94011d3 364 *
sahilmgandhi 18:6a4db94011d3 365 * \param[in] events Struct containing flags of events to enable
sahilmgandhi 18:6a4db94011d3 366 */
sahilmgandhi 18:6a4db94011d3 367 void extint_enable_events(
sahilmgandhi 18:6a4db94011d3 368 struct extint_events *const events)
sahilmgandhi 18:6a4db94011d3 369 {
sahilmgandhi 18:6a4db94011d3 370 /* Sanity check arguments */
sahilmgandhi 18:6a4db94011d3 371 Assert(events);
sahilmgandhi 18:6a4db94011d3 372
sahilmgandhi 18:6a4db94011d3 373 /* Array of available EICs. */
sahilmgandhi 18:6a4db94011d3 374 Eic *const eics[EIC_INST_NUM] = EIC_INSTS;
sahilmgandhi 18:6a4db94011d3 375
sahilmgandhi 18:6a4db94011d3 376 /* Update the event control register for each physical EIC instance */
sahilmgandhi 18:6a4db94011d3 377 for (uint32_t i = 0; i < EIC_INST_NUM; i++) {
sahilmgandhi 18:6a4db94011d3 378 uint32_t event_mask = 0;
sahilmgandhi 18:6a4db94011d3 379
sahilmgandhi 18:6a4db94011d3 380 /* Create an enable mask for the current EIC module */
sahilmgandhi 18:6a4db94011d3 381 for (uint32_t j = 0; j < 32; j++) {
sahilmgandhi 18:6a4db94011d3 382 if (events->generate_event_on_detect[(32 * i) + j]) {
sahilmgandhi 18:6a4db94011d3 383 event_mask |= (1UL << j);
sahilmgandhi 18:6a4db94011d3 384 }
sahilmgandhi 18:6a4db94011d3 385 }
sahilmgandhi 18:6a4db94011d3 386
sahilmgandhi 18:6a4db94011d3 387 /* Enable the masked events */
sahilmgandhi 18:6a4db94011d3 388 eics[i]->EVCTRL.reg |= event_mask;
sahilmgandhi 18:6a4db94011d3 389 }
sahilmgandhi 18:6a4db94011d3 390 }
sahilmgandhi 18:6a4db94011d3 391
sahilmgandhi 18:6a4db94011d3 392 /**
sahilmgandhi 18:6a4db94011d3 393 * \brief Disables an External Interrupt event output.
sahilmgandhi 18:6a4db94011d3 394 *
sahilmgandhi 18:6a4db94011d3 395 * Disables one or more output events from the External Interrupt module. See
sahilmgandhi 18:6a4db94011d3 396 * \ref extint_events "here" for a list of events this module supports.
sahilmgandhi 18:6a4db94011d3 397 *
sahilmgandhi 18:6a4db94011d3 398 * \note Events cannot be altered while the module is enabled.
sahilmgandhi 18:6a4db94011d3 399 *
sahilmgandhi 18:6a4db94011d3 400 * \param[in] events Struct containing flags of events to disable
sahilmgandhi 18:6a4db94011d3 401 */
sahilmgandhi 18:6a4db94011d3 402 void extint_disable_events(
sahilmgandhi 18:6a4db94011d3 403 struct extint_events *const events)
sahilmgandhi 18:6a4db94011d3 404 {
sahilmgandhi 18:6a4db94011d3 405 /* Sanity check arguments */
sahilmgandhi 18:6a4db94011d3 406 Assert(events);
sahilmgandhi 18:6a4db94011d3 407
sahilmgandhi 18:6a4db94011d3 408 /* Array of available EICs. */
sahilmgandhi 18:6a4db94011d3 409 Eic *const eics[EIC_INST_NUM] = EIC_INSTS;
sahilmgandhi 18:6a4db94011d3 410
sahilmgandhi 18:6a4db94011d3 411 /* Update the event control register for each physical EIC instance */
sahilmgandhi 18:6a4db94011d3 412 for (uint32_t i = 0; i < EIC_INST_NUM; i++) {
sahilmgandhi 18:6a4db94011d3 413 uint32_t event_mask = 0;
sahilmgandhi 18:6a4db94011d3 414
sahilmgandhi 18:6a4db94011d3 415 /* Create a disable mask for the current EIC module */
sahilmgandhi 18:6a4db94011d3 416 for (uint32_t j = 0; j < 32; j++) {
sahilmgandhi 18:6a4db94011d3 417 if (events->generate_event_on_detect[(32 * i) + j]) {
sahilmgandhi 18:6a4db94011d3 418 event_mask |= (1UL << j);
sahilmgandhi 18:6a4db94011d3 419 }
sahilmgandhi 18:6a4db94011d3 420 }
sahilmgandhi 18:6a4db94011d3 421
sahilmgandhi 18:6a4db94011d3 422 /* Disable the masked events */
sahilmgandhi 18:6a4db94011d3 423 eics[i]->EVCTRL.reg &= ~event_mask;
sahilmgandhi 18:6a4db94011d3 424 }
sahilmgandhi 18:6a4db94011d3 425 }