Example #1
0
/**
 * \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();
}
Example #2
0
/**
 * \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);
	}
}
Example #3
0
/**
 * \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;
}
Example #4
0
/**
 * \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;
}