Example #1
0
enum status_code events_add_hook(struct events_resource *resource, struct events_hook *hook)
{
	struct events_hook *tmp_hook = NULL;

	/* Associate the hook with the resource */
	hook->resource = resource;

	/* Check if this is the first hook in the list */
	if (_events_inst.hook_list == NULL) {
		_events_inst.hook_list = hook;
	} else {
		tmp_hook = _events_inst.hook_list;

		/* Find the first free place in the list */
		while (tmp_hook->next != NULL) {
			tmp_hook = tmp_hook->next;
		}

		/* Put the hook into the next free place in the list */
		tmp_hook->next = hook;
	}

	/* Check if interrupts from the EVSYS module is enabled in the interrupt controller */
	if (!system_interrupt_is_enabled(SYSTEM_INTERRUPT_MODULE_EVSYS)) {
		system_interrupt_enable(SYSTEM_INTERRUPT_MODULE_EVSYS);
	}

	return STATUS_OK;
}
int main(void)
{
	system_init();

//! [main_1]
//! [critical_section_start]
	system_interrupt_enter_critical_section();
//! [critical_section_start]

//! [do_critical_code]
	if (is_ready == true) {
		/* Do something in response to the global shared flag */
		is_ready = false;
	}
//! [do_critical_code]

//! [critical_section_end]
	system_interrupt_leave_critical_section();
//! [critical_section_end]
//! [main_1]

//! [main_2]
//! [module_int_enable]
	system_interrupt_enable(SYSTEM_INTERRUPT_MODULE_RTC);
//! [module_int_enable]

//! [global_int_enable]
	system_interrupt_enable_global();
//! [global_int_enable]
//! [main_2]

	while (true) {
		/* Infinite loop */
	}
}
Example #3
0
File: i2s.c Project: Realtime-7/asf
/**
 * \brief Initializes a hardware I2S module instance
 *
 * Enables the clock and initialize the I2S module.
 *
 * \param[in,out] module_inst  Pointer to the software module instance struct
 * \param[in]     hw           Pointer to the TCC hardware module
 *
 * \return Status of the initialization procedure.
 *
 * \retval STATUS_OK           The module was initialized successfully
 * \retval STATUS_BUSY         Hardware module was busy when the
 *                             initialization procedure was attempted
 * \retval STATUS_ERR_DENIED   Hardware module was already enabled
 */
enum status_code i2s_init(
		struct i2s_module *const module_inst,
		I2s *hw)
{
	Assert(module_inst);
	Assert(hw);

	/* Enable the user interface clock in the PM */
	system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, PM_APBCMASK_I2S);

	/* Status check */
	uint32_t ctrla;
	ctrla = module_inst->hw->CTRLA.reg;
	if (ctrla & I2S_CTRLA_ENABLE) {
		if (ctrla & (I2S_CTRLA_SEREN1 |
				I2S_CTRLA_SEREN0 | I2S_CTRLA_CKEN1 | I2S_CTRLA_CKEN0)) {
			return STATUS_BUSY;
		} else {
			return STATUS_ERR_DENIED;
		}
	}

	/* Initialize module */
	module_inst->hw = hw;

	/* Initialize serializers */
#if I2S_CALLBACK_MODE == true
	int i, j;
	for (i = 0; i < 2; i ++) {
		for (j = 0; j < I2S_SERIALIZER_CALLBACK_N; j ++) {
			module_inst->serializer[i].callback[j] = NULL;
		}
		module_inst->serializer[i].registered_callback_mask = 0;
		module_inst->serializer[i].enabled_callback_mask = 0;

		module_inst->serializer[i].job_buffer = NULL;
		module_inst->serializer[i].job_status = STATUS_OK;
		module_inst->serializer[i].requested_words = 0;
		module_inst->serializer[i].transferred_words = 0;

		module_inst->serializer[i].mode = I2S_SERIALIZER_RECEIVE;
		module_inst->serializer[i].data_size = I2S_DATA_SIZE_32BIT;
	}

	_i2s_instances[0] = module_inst;

	system_interrupt_enable(SYSTEM_INTERRUPT_MODULE_I2S);
#endif

	return STATUS_OK;
}
Example #4
0
void _system_extint_init(void)
{
	Eic *const eics[EIC_INST_NUM] = EIC_INSTS;

	/* Turn on the digital interface clock */
	system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBA, MCLK_APBAMASK_EIC);

#if (EXTINT_CLOCK_SELECTION == EXTINT_CLK_GCLK)
	/* Configure the generic clock for the module and enable it */
	struct system_gclk_chan_config gclk_chan_conf;
	system_gclk_chan_get_config_defaults(&gclk_chan_conf);
	gclk_chan_conf.source_generator = EXTINT_CLOCK_SOURCE;
	system_gclk_chan_set_config(EIC_GCLK_ID, &gclk_chan_conf);

	/* Enable the clock anyway, since when needed it will be requested
	 * by External Interrupt driver */
	system_gclk_chan_enable(EIC_GCLK_ID);
#endif

	/* Reset all EIC hardware modules. */
	for (uint32_t i = 0; i < EIC_INST_NUM; i++) {
		eics[i]->CTRLA.reg |= EIC_CTRLA_SWRST;
	}

	while (extint_is_syncing()) {
		/* Wait for all hardware modules to complete synchronization */
	}

#if (EXTINT_CLOCK_SELECTION == EXTINT_CLK_GCLK)
	for (uint32_t i = 0; i < EIC_INST_NUM; i++) {
		eics[i]->CTRLA.bit.CKSEL = EXTINT_CLK_GCLK;
	}
#else
	for (uint32_t i = 0; i < EIC_INST_NUM; i++) {
		eics[i]->CTRLA.bit.CKSEL = EXTINT_CLK_ULP32K;
	}
#endif

	/* Reset the software module */
#if EXTINT_CALLBACK_MODE == true
	/* Clear callback registration table */
	for (uint8_t j = 0; j < EIC_NUMBER_OF_INTERRUPTS; j++) {
		_extint_dev.callbacks[j] = NULL;
	}
	system_interrupt_enable(SYSTEM_INTERRUPT_MODULE_EIC);
#endif

	/* Enables the driver for further use */
	_extint_enable();
}
Example #5
0
/**
 * \brief Enable the SERCOM SPI module
 *
 * This function must be called after \ref spi_master_vec_init() before a
 * transfer can be started.
 *
 * \param[in,out] module Driver instance to operate on.
 */
void spi_master_vec_enable(const struct spi_master_vec_module *const module)
{
	Assert(module);
	Assert(module->sercom);

	SercomSpi *const spi_hw = &(module->sercom->SPI);

	spi_hw->INTENCLR.reg = SERCOM_SPI_INTFLAG_DRE | SERCOM_SPI_INTFLAG_RXC
			| SERCOM_SPI_INTFLAG_TXC;

	_spi_master_vec_wait_for_sync(spi_hw);

	spi_hw->CTRLA.reg |= SERCOM_SPI_CTRLA_ENABLE;

	system_interrupt_enable(_sercom_get_interrupt_vector(module->sercom));
}
/**
 * \brief Disables callback
 *
 * Disables the callback function registered by the \ref
 * tcc_register_callback, and the callback will not be called from the
 * interrupt routine. The function will also disable the appropriate
 * interrupts.
 *
 * \param[in]     module Pointer to TCC software instance struct
 * \param[in]     callback_type Callback type given by an enum
 */
void tcc_disable_callback(
		struct tcc_module *const module,
		const enum tcc_callback callback_type)
{
	/* Sanity check arguments */
	Assert(module);
	Assert(module->hw);

	/* Disable interrupts for this TCC module */
	system_interrupt_enable(_tcc_interrupt_get_interrupt_vector(
			_tcc_get_inst_index(module->hw)));

	/* Disable channel or other callbacks */
	module->enable_callback_mask &= ~_tcc_intflag[callback_type];
	module->hw->INTENCLR.reg = _tcc_intflag[callback_type];
}
Example #7
0
/**
 * \brief Enables asynchronous callback generation for a given type.
 *
 * Enables asynchronous callbacks for a given callback type. This must be
 * called before an external interrupt channel will generate callback events.
 *
 * \param[in] type  Type of callback function to enable
 *
 * \return Status of the callback enable operation.
 * \retval STATUS_OK               The callback was enabled successfully
 * \retval STATUS_ERR_INVALID_ARG  If an invalid callback type was supplied
 */
enum status_code wdt_enable_callback(
		const enum wdt_callback type)
{
	Wdt *const WDT_module = WDT;

	switch (type)
	{
	case WDT_CALLBACK_EARLY_WARNING:
		WDT_module->INTENSET.reg = WDT_INTENSET_EW;
		system_interrupt_enable(SYSTEM_INTERRUPT_MODULE_WDT);
		return STATUS_OK;
	default:
		Assert(false);
		return STATUS_ERR_INVALID_ARG;
	}
}
/**
 * \brief Convert a specific number digital data to analog through DAC.
 *
 * This function will perform a conversion of specific number of digital data.
 * The conversion should be event-triggered, the data will be written to DATABUF
 * and transferred to the DATA register and converted when a Start Conversion
 * Event is issued.
 * Conversion data must be right or left adjusted according to configuration
 * settings.
 * \note To be event triggered, the enable_start_on_event must be
 * enabled in the configuration.
 *
 * \param[in] module_inst      Pointer to the DAC software device struct
 * \param[in] channel          DAC channel to write to
 * \param[in] buffer             Pointer to the digital data write buffer to be converted
 * \param[in] length             Size of the write buffer
 *
 * \return Status of the operation.
 * \retval STATUS_OK           If the data was written
 * \retval STATUS_ERR_UNSUPPORTED_DEV  If a callback that requires event driven
 *                                     mode was specified with a DAC instance
 *                                     configured in non-event mode
 * \retval STATUS_BUSY      The DAC is busy to accept new job
 */
enum status_code dac_chan_write_buffer_job(
		struct dac_module *const module_inst,
		const enum dac_channel channel,
		uint16_t *buffer,
		uint32_t length)
{
	/* Sanity check arguments */
	Assert(module_inst);
	Assert(module_inst->hw);
	Assert(buffer);

	UNUSED(channel);

	Dac *const dac_module = module_inst->hw;

	/* DAC interrupts require it to be driven by events to work, fail if in
	 * unbuffered (polled) mode */
	if (module_inst->start_on_event == false) {
		return STATUS_ERR_UNSUPPORTED_DEV;
	}

	if(module_inst->remaining_conversions != 0 ||
			module_inst->job_status == STATUS_BUSY){
		return STATUS_BUSY;
	}

	/* Wait until the synchronization is complete */
	while (dac_is_syncing(module_inst)) {
	};

	module_inst->job_status = STATUS_BUSY;

	module_inst->remaining_conversions = length;
	module_inst->job_buffer = buffer;
	module_inst->transferred_conversions = 0;

	/* Enable interrupt */
	system_interrupt_enable(SYSTEM_INTERRUPT_MODULE_DAC);
	dac_module->INTFLAG.reg = DAC_INTFLAG_UNDERRUN | DAC_INTFLAG_EMPTY;
	dac_module->INTENSET.reg = DAC_INTENSET_UNDERRUN | DAC_INTENSET_EMPTY;

	return STATUS_OK;
}
Example #9
0
/**
 * \brief Enables the RTC module.
 *
 * Enables the RTC module once it has been configured, ready for use. Most
 * module configuration parameters cannot be altered while the module is enabled.
 *
 * \param[in,out]  module  RTC hardware module
 */
void rtc_count_enable(struct rtc_module *const module)
{
	/* Sanity check arguments */
	Assert(module);
	Assert(module->hw);

	Rtc *const rtc_module = module->hw;

#if RTC_COUNT_ASYNC == true
	system_interrupt_enable(SYSTEM_INTERRUPT_MODULE_RTC);
#endif

	while (rtc_count_is_syncing(module)) {
		/* Wait for synchronization */
	}

	/* Enable RTC module. */
	rtc_module->MODE0.CTRL.reg |= RTC_MODE0_CTRL_ENABLE;
}
Example #10
0
/**
 * \brief Registers a callback
 *
 * Registers a callback function which is implemented by the user.
 *
 * \note The callback must be enabled by \ref trng_enable_callback,
 * in order for the interrupt handler to call it when the conditions for the
 * callback type is met.
 *
 * \param[in]     module        Pointer to TC software instance struct
 * \param[in]     callback_func Pointer to callback function
 * \param[in]     callback_type Callback type given by an enum
 *
 * \retval STATUS_OK  The function exited successfully
 */
enum status_code trng_register_callback(
		struct trng_module *const module,
		trng_callback_t callback_func,
		const enum trng_callback callback_type)
{
	/* Sanity check arguments */
	Assert(module);
	Assert(callback_func);

	/* Register callback function */
	module->callback[callback_type] = callback_func;

	/* Set the bit corresponding to the callback_type */
	module->register_callback_mask |= (1 << callback_type);

	/* Enable interrupt for this TRNG module */
	system_interrupt_enable(SYSTEM_INTERRUPT_MODULE_TRNG);

	return STATUS_OK;
}
Example #11
0
/**
 * \brief Enable the SERCOM SPI module
 *
 * This function must be called after \ref spi_master_vec_init() before a
 * transfer can be started.
 *
 * \param[in,out] module Driver instance to operate on.
 */
void spi_master_vec_enable(const struct spi_master_vec_module *const module)
{
	Assert(module);
	Assert(module->sercom);

	SercomSpi *const spi_hw = &(module->sercom->SPI);

	spi_hw->INTENCLR.reg = SERCOM_SPI_INTFLAG_DRE | SERCOM_SPI_INTFLAG_RXC
			| SERCOM_SPI_INTFLAG_TXC;

#  ifdef FEATURE_SPI_SYNC_SCHEME_VERSION_2
	while (spi_hw->STATUS.reg) {
		/* Intentionally left empty */
	}
#  else
	while (spi_hw->STATUS.reg & SERCOM_SPI_STATUS_SYNCBUSY) {
		/* Intentionally left empty */
	}
#  endif
	spi_hw->CTRLA.reg |= SERCOM_SPI_CTRLA_ENABLE;

	system_interrupt_enable(_sercom_get_interrupt_vector(module->sercom));
}