예제 #1
0
/**
 * \brief Sets the ADC window mode
 *
 * Sets the ADC window mode to a given mode and value range.
 *
 * \param[in] module_inst         Pointer to the ADC software instance struct
 * \param[in] window_mode         Window monitor mode to set
 * \param[in] window_lower_value  Lower window monitor threshold value
 * \param[in] window_upper_value  Upper window monitor threshold value
  */
void adc_set_window_mode(
		struct adc_module *const module_inst,
		const enum adc_window_mode window_mode,
		const int16_t window_lower_value,
		const int16_t window_upper_value)
{
	/* Sanity check arguments */
	Assert(module_inst);
	Assert(module_inst->hw);

	Adc *const adc_module = module_inst->hw;

	while (adc_is_syncing(module_inst)) {
		/* Wait for synchronization */
	}

	/* Set window mode */
	adc_module->WINCTRL.reg = window_mode << ADC_WINCTRL_WINMODE_Pos;

	while (adc_is_syncing(module_inst)) {
		/* Wait for synchronization */
	}

	/* Set lower window monitor threshold value */
	adc_module->WINLT.reg = window_lower_value << ADC_WINLT_WINLT_Pos;

	while (adc_is_syncing(module_inst)) {
		/* Wait for synchronization */
	}

	/* Set upper window monitor threshold value */
	adc_module->WINUT.reg = window_upper_value << ADC_WINUT_WINUT_Pos;
}
예제 #2
0
static void _adc_interrupt_handler(const uint8_t instance)
{
	struct adc_module *module = _adc_instances[instance];

	/* get interrupt flags and mask out enabled callbacks */
	uint32_t flags = module->hw->INTFLAG.reg;

	if (flags & ADC_INTFLAG_RESRDY) {
		if ((module->enabled_callback_mask & (1 << ADC_CALLBACK_READ_BUFFER)) &&
				(module->registered_callback_mask & (1 << ADC_CALLBACK_READ_BUFFER))) {
			/* clear interrupt flag */
			module->hw->INTFLAG.reg = ADC_INTFLAG_RESRDY;

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

			/* store ADC result in job buffer */
			*(module->job_buffer++) = module->hw->RESULT.reg;

			if (--module->remaining_conversions > 0) {
				if (module->software_trigger == true) {
					adc_start_conversion(module);
				}
			} else {
				if (module->job_status == STATUS_BUSY) {
					/* job is complete. update status,disable interrupt
					 *and call callback */
					module->job_status = STATUS_OK;
					adc_disable_interrupt(module, ADC_INTERRUPT_RESULT_READY);

					(module->callback[ADC_CALLBACK_READ_BUFFER])(module);
				}
			}
		}
	}

	if (flags & ADC_INTFLAG_WINMON) {
		module->hw->INTFLAG.reg = ADC_INTFLAG_WINMON;
		if ((module->enabled_callback_mask & (1 << ADC_CALLBACK_WINDOW)) &&
				(module->registered_callback_mask & (1 << ADC_CALLBACK_WINDOW))) {
			(module->callback[ADC_CALLBACK_WINDOW])(module);
		}

	}

	if (flags & ADC_INTFLAG_OVERRUN) {
		module->hw->INTFLAG.reg = ADC_INTFLAG_OVERRUN;
		if ((module->enabled_callback_mask & (1 << ADC_CALLBACK_ERROR)) &&
				(module->registered_callback_mask & (1 << ADC_CALLBACK_ERROR))) {
			(module->callback[ADC_CALLBACK_ERROR])(module);
		}
	}
}