/** * \brief Writes an External Interrupt channel configuration to the hardware module. * * Writes out a given configuration of an External Interrupt channel * configuration to the hardware module. If the channel is already configured, * the new configuration will replace the existing one. * * \param[in] channel External Interrupt channel to configure * \param[in] config Configuration settings for the channel */ void extint_chan_set_config( const uint8_t channel, const struct extint_chan_conf *const config) { /* Sanity check arguments */ Assert(config); _extint_disable(); #if(EXTINT_CLOCK_SELECTION == EXTINT_CLK_GCLK) /* Sanity check clock requirements */ Assert(!(!system_gclk_gen_is_enabled(EXTINT_CLOCK_SOURCE) && _extint_is_gclk_required(config->filter_input_signal, config->detection_criteria))); #endif struct system_pinmux_config pinmux_config; system_pinmux_get_config_defaults(&pinmux_config); pinmux_config.mux_position = config->gpio_pin_mux; pinmux_config.direction = SYSTEM_PINMUX_PIN_DIR_INPUT; pinmux_config.input_pull = (enum system_pinmux_pin_pull)config->gpio_pin_pull; system_pinmux_pin_set_config(config->gpio_pin, &pinmux_config); /* Get a pointer to the module hardware instance */ Eic *const EIC_module = _extint_get_eic_from_channel(channel); uint32_t config_pos = (4 * (channel % 8)); uint32_t new_config; /* Determine the channel's new edge detection configuration */ new_config = (config->detection_criteria << EIC_CONFIG_SENSE0_Pos); /* Enable the hardware signal filter if requested in the config */ if (config->filter_input_signal) { new_config |= EIC_CONFIG_FILTEN0; } /* Clear the existing and set the new channel configuration */ EIC_module->CONFIG[channel / 8].reg = (EIC_module->CONFIG[channel / 8].reg & ~((EIC_CONFIG_SENSE0_Msk | EIC_CONFIG_FILTEN0) << config_pos)) | (new_config << config_pos); #if (SAML22) || (SAML21XXXB) || (SAMC20) || (SAMR30) /* Config asynchronous edge detection */ if (config->enable_async_edge_detection) { EIC_module->ASYNCH.reg |= (1UL << channel); } else { EIC_module->ASYNCH.reg &= (EIC_ASYNCH_MASK & (~(1UL << channel))); } #endif #if (SAMC21) /* Config asynchronous edge detection */ if (config->enable_async_edge_detection) { EIC_module->EIC_ASYNCH.reg |= (1UL << channel); } else { EIC_module->EIC_ASYNCH.reg &= (EIC_EIC_ASYNCH_MASK & (~(1UL << channel))); } #endif _extint_enable(); }
/** * \brief Writes an External Interrupt channel configuration to the hardware module. * * Writes out a given configuration of an External Interrupt channel * configuration to the hardware module. If the channel is already configured, * the new configuration will replace the existing one. * * \param[in] channel External Interrupt channel to configure * \param[in] config Configuration settings for the channel */ void extint_chan_set_config( const uint8_t channel, const struct extint_chan_conf *const config) { /* Sanity check arguments */ Assert(config); /* Sanity check clock requirements */ Assert(!(!system_gclk_gen_is_enabled(EXTINT_CLOCK_SOURCE) && _extint_is_gclk_required(config->filter_input_signal, config->detection_criteria))); struct system_pinmux_config pinmux_config; system_pinmux_get_config_defaults(&pinmux_config); pinmux_config.mux_position = config->gpio_pin_mux; pinmux_config.direction = SYSTEM_PINMUX_PIN_DIR_INPUT; pinmux_config.input_pull = (enum system_pinmux_pin_pull)config->gpio_pin_pull; system_pinmux_pin_set_config(config->gpio_pin, &pinmux_config); /* Get a pointer to the module hardware instance */ Eic *const EIC_module = _extint_get_eic_from_channel(channel); uint32_t config_pos = (4 * (channel % 8)); uint32_t new_config; /* Determine the channel's new edge detection configuration */ new_config = (config->detection_criteria << EIC_CONFIG_SENSE0_Pos); /* Enable the hardware signal filter if requested in the config */ if (config->filter_input_signal) { new_config |= EIC_CONFIG_FILTEN0; } /* Clear the existing and set the new channel configuration */ EIC_module->CONFIG[channel / 8].reg = (EIC_module->CONFIG[channel / 8].reg & ~((EIC_CONFIG_SENSE0_Msk | EIC_CONFIG_FILTEN0) << config_pos)) | (new_config << config_pos); /* Set the channel's new wake up mode setting */ if (config->wake_if_sleeping) { EIC_module->WAKEUP.reg |= (1UL << channel); } else { EIC_module->WAKEUP.reg &= ~(1UL << channel); } }
/** * \brief Writes an External Interrupt NMI channel configuration to the hardware module. * * Writes out a given configuration of an External Interrupt NMI channel * configuration to the hardware module. If the channel is already configured, * the new configuration will replace the existing one. * * \param[in] nmi_channel External Interrupt NMI channel to configure * \param[in] config Configuration settings for the channel * * \returns Status code indicating the success or failure of the request. * \retval STATUS_OK Configuration succeeded * \retval STATUS_ERR_PIN_MUX_INVALID An invalid pinmux value was supplied * \retval STATUS_ERR_BAD_FORMAT An invalid detection mode was requested */ enum status_code extint_nmi_set_config( const uint8_t nmi_channel, const struct extint_nmi_conf *const config) { /* Sanity check arguments */ Assert(config); /* Sanity check clock requirements */ Assert(!(!system_gclk_gen_is_enabled(EXTINT_CLOCK_SOURCE) && _extint_is_gclk_required(config->filter_input_signal, config->detection_criteria))); struct system_pinmux_config pinmux_config; system_pinmux_get_config_defaults(&pinmux_config); pinmux_config.mux_position = config->gpio_pin_mux; pinmux_config.direction = SYSTEM_PINMUX_PIN_DIR_INPUT; pinmux_config.input_pull = SYSTEM_PINMUX_PIN_PULL_UP; pinmux_config.input_pull = (enum system_pinmux_pin_pull)config->gpio_pin_pull; system_pinmux_pin_set_config(config->gpio_pin, &pinmux_config); /* Get a pointer to the module hardware instance */ Eic *const EIC_module = _extint_get_eic_from_channel(nmi_channel); uint32_t new_config; /* Determine the NMI's new edge detection configuration */ new_config = (config->detection_criteria << EIC_NMICTRL_NMISENSE_Pos); /* Enable the hardware signal filter if requested in the config */ if (config->filter_input_signal) { new_config |= EIC_NMICTRL_NMIFILTEN; } /* Disable EIC and general clock to configure NMI */ _extint_disable(); system_gclk_chan_disable(EIC_GCLK_ID); EIC_module->NMICTRL.reg = new_config; /* Enable the general clock and EIC after configure NMI */ system_gclk_chan_enable(EIC_GCLK_ID); _extint_enable(); return STATUS_OK; }
/** * \brief Writes an External Interrupt NMI channel configuration to the hardware module. * * Writes out a given configuration of an External Interrupt NMI channel * configuration to the hardware module. If the channel is already configured, * the new configuration will replace the existing one. * * \param[in] nmi_channel External Interrupt NMI channel to configure * \param[in] config Configuration settings for the channel * * \returns Status code indicating the success or failure of the request. * \retval STATUS_OK Configuration succeeded * \retval STATUS_ERR_PIN_MUX_INVALID An invalid pin mux value was supplied * \retval STATUS_ERR_BAD_FORMAT An invalid detection mode was requested */ enum status_code extint_nmi_set_config( const uint8_t nmi_channel, const struct extint_nmi_conf *const config) { /* Sanity check arguments */ Assert(config); /* Sanity check clock requirements */ Assert(!(!system_gclk_gen_is_enabled(EXTINT_CLOCK_SOURCE) && _extint_is_gclk_required(config->filter_input_signal, config->detection_criteria))); struct system_pinmux_config pinmux_config; system_pinmux_get_config_defaults(&pinmux_config); pinmux_config.mux_position = config->gpio_pin_mux; pinmux_config.direction = SYSTEM_PINMUX_PIN_DIR_INPUT; pinmux_config.input_pull = SYSTEM_PINMUX_PIN_PULL_UP; pinmux_config.input_pull = (enum system_pinmux_pin_pull)config->gpio_pin_pull; system_pinmux_pin_set_config(config->gpio_pin, &pinmux_config); /* Get a pointer to the module hardware instance */ Eic *const EIC_module = _extint_get_eic_from_channel(nmi_channel); uint32_t new_config; /* Determine the NMI's new edge detection configuration */ new_config = (config->detection_criteria << EIC_NMICTRL_NMISENSE_Pos); /* Enable the hardware signal filter if requested in the config */ if (config->filter_input_signal) { new_config |= EIC_NMICTRL_NMIFILTEN; } #if (SAML21XXXB) || (SAML22) || (SAMC21) || (SAMR30) /* Enable asynchronous edge detection if requested in the config */ if (config->enable_async_edge_detection) { new_config |= EIC_NMICTRL_NMIASYNCH; } #endif /* Disable EIC and general clock to configure NMI */ _extint_disable(); #if(EXTINT_CLOCK_SELECTION == EXTINT_CLK_GCLK) system_gclk_chan_disable(EIC_GCLK_ID); #else Eic *const eics[EIC_INST_NUM] = EIC_INSTS; for (uint32_t i = 0; i < EIC_INST_NUM; i++){ eics[i]->CTRLA.bit.CKSEL = EXTINT_CLK_GCLK; system_gclk_chan_disable(EIC_GCLK_ID); } #endif EIC_module->NMICTRL.reg = new_config; /* Enable the EIC clock and EIC after configure NMI */ #if(EXTINT_CLOCK_SELECTION == EXTINT_CLK_GCLK) system_gclk_chan_enable(EIC_GCLK_ID); #else for (uint32_t i = 0; i < EIC_INST_NUM; i++){ eics[i]->CTRLA.bit.CKSEL = EXTINT_CLK_ULP32K; } #endif _extint_enable(); return STATUS_OK; }