/**
 * \brief Measures and enables offset and gain corrections
 */
static void main_adc_correction(void)
{
	/* ADC channel configuration structure */
	struct adc_channel_config adcch_conf;
	uint16_t offset_correction;

	/* Expected value for gain correction at 1.9V
	 * expected_value = Max. range * 1.9V / (VCC / 1.6)
	 * Max. range = 12 bits signed = 11 bits unsigned
	 */
	const uint16_t expected_value
		= ((1 << 11) * 1900UL) / (3300L * 1000L / 1600L);
	/* Captured value for gain correction */
	uint16_t captured_value;

	/* DAC Output 0 Volt */
	main_dac_output(0);

	/* Capture value for 0 Volt */
	adc_start_conversion(&ADCA, ADC_CH0);
	adc_wait_for_interrupt_flag(&ADCA, ADC_CH0);
	offset_correction = adc_get_unsigned_result(&ADCA, ADC_CH0);

	/* Enable offset correction */
	adcch_read_configuration(&ADCA, ADC_CH0, &adcch_conf);
	adcch_enable_correction(&adcch_conf, offset_correction, 1, 1);
	adcch_write_configuration(&ADCA, ADC_CH0, &adcch_conf);

	/* DAC Output 1.9 Volts */
	main_dac_output(1900);

	/* Capture value for 1.9 Volts */
	adc_start_conversion(&ADCA, ADC_CH0);
	adc_wait_for_interrupt_flag(&ADCA, ADC_CH0);
	captured_value = adc_get_unsigned_result(&ADCA, ADC_CH0);

	/* Enable offset & gain correction */
	adcch_enable_correction(&adcch_conf, offset_correction, expected_value,
			captured_value);
	adcch_write_configuration(&ADCA, ADC_CH0, &adcch_conf);

	printf("\n\r*** ADC correction:  ");
	printf("Offset correction %d,   ", offset_correction);
	if (expected_value > captured_value) {
		printf("Gain correction 1.%03u\n\r\n\r", (uint16_t)
				((((uint32_t)expected_value - captured_value)
				* 1000) / captured_value));
	} else {
		printf("Gain correction 0.%03u\n\r\n\r", (uint16_t)
				(((uint32_t)expected_value
				* 1000) / captured_value));
	}
}
Exemplo n.º 2
0
/**
 * \brief Callback function for ADC interrupts
 *
 * \param adc Pointer to ADC module.
 * \param channel ADC channel number.
 * \param result Conversion result from ADC channel.
 */
static void adc_handler(ADC_t *adc, uint8_t channel, adc_result_t result)
{
	switch (adc_conv[adc_mux_index].in) {
		case EXT_VIN_ADC_INPUT:
			ext_voltage=result;
			adc_mux_index++;

			//start new measurement
			adc_disable(&EXT_VIN_ADC_MODULE);
			adc_set_conversion_parameters(&adc_conf
					,ADC_SIGN_OFF
					,ADC_RES_12
					,adc_conv[adc_mux_index].ref);
			adc_write_configuration(
					&POTENTIOMETER_ADC_MODULE
					, &adc_conf);
			adc_enable(&POTENTIOMETER_ADC_MODULE);
			adcch_set_input(&adcch_conf
					,adc_conv[adc_mux_index].in
					,ADCCH_NEG_NONE,1);
			adcch_write_configuration(
					&POTENTIOMETER_ADC_MODULE
					, ADC_CH0, &adcch_conf);
			adc_start_conversion(&POTENTIOMETER_ADC_MODULE
					, ADC_CH0);
			break;
		case POTENTIOMETER_ADC_INPUT:
			potentiometer=result;
		break;

		default:
		break;
	}
}
Exemplo n.º 3
0
void test_adc (void)
{
	uint8_t i = 0;

	while (1)
	{
		/* ADC software trigger per 100ms */
		if (_test_mode.trigger_mode == TRIGGER_MODE_SOFTWARE) {
			if (timer_timeout_reached(&timeout) && !_data.done) {
				adc_start_conversion();
				timer_start_timeout(&timeout, 250);
			}
		}
		if (_test_mode.trigger_mode == TRIGGER_MODE_ADTRG) {
			if (pio_get_output_data_status(&pin_adtrg[0]))
				pio_clear(&pin_adtrg[0]);
			else
				pio_set(&pin_adtrg[0]);
		}
		/* Check if ADC sample is done */
		if (_data.done & ADC_DONE_MASK) {
			for (i = 0; i < NUM_CHANNELS; ++i) {
				printf(" CH%02d: %04d ", _data.channel[i],
					   (_data.value[i]* VREF/MAX_DIGITAL) );
			}
			printf("\r");
			_data.done = 0;
		}
	}
}
Exemplo n.º 4
0
int main(void)
{
	system_init();

//! [setup_init]
	configure_adc();
//! [setup_init]

//! [main]
//! [start_conv]
	adc_start_conversion(&adc_instance);
//! [start_conv]

//! [get_res]
	uint16_t result;

	do {
		/* Wait for conversion to be done and read out result */
	} while (adc_read(&adc_instance, &result) == STATUS_BUSY);
//! [get_res]

//! [inf_loop]
	while (1) {
		/* Infinite loop */
	}
//! [inf_loop]
//! [main]
}
Exemplo n.º 5
0
/**
 * \brief Reads a 16-bit analog value on ADC channel 0 and returns it.
 *
 * In this application CH0 is set up to read the analog voltage from
 * a simulated thermometer.
 *
 * \return Temperature of the induction element.
 */
uint16_t ovenctl_get_plate_temperature(void)
{
	adc_start_conversion(&ADCA, ADC_CH0);
	adc_wait_for_interrupt_flag(&ADCA, ADC_CH0);

	return adc_get_unsigned_result(&ADCA, ADC_CH0) / 4;
}
Exemplo n.º 6
0
uint16_t adp_example_adc_get_value(void)
{
	uint16_t result;
	adc_start_conversion(&adc_instance);
	while (adc_read(&adc_instance, &result) == STATUS_BUSY);
	return result;
}
Exemplo n.º 7
0
/**
 * \brief Callback function for ADC interrupts
 *
 * \param adc Pointer to ADC module.
 * \param ch_mask ADC channel mask.
 * \param result Conversion result from ADC channel.
 */
static void adc_handler(ADC_t *adc, uint8_t ch_mask, adc_result_t result)
{
	int32_t temperature;
	char out_str[OUTPUT_STR_SIZE];

	/* Compute current temperature in Celsius, based on linearization
	 * of the temperature sensor adc data.
	 */

	if (result > 697) {
		temperature = (int8_t)((-0.0295 * result) + 40.5);
	} if (result > 420) {
		temperature = (int8_t)((-0.0474 * result) + 53.3);
	} else {
		temperature = (int8_t)((-0.0777 * result) + 65.1);
	}

	last_temperature = temperature;

	// Write temperature to display
	snprintf(out_str, OUTPUT_STR_SIZE, "Temperature: %4d C", last_temperature);
	gfx_mono_draw_string(out_str, 0, 0, &sysfont);

	// Start next conversion.
	adc_start_conversion(adc, ch_mask);
}
Exemplo n.º 8
0
//for manually reading adc channels
uint16_t adc_read(uint8_t channel)
{
  adc_start_conversion(channel);
  loop_until_bit_is_clear(ADCSRA, ADSC);

  return ADCW;
}
Exemplo n.º 9
0
/**
 * \brief Initialize ADC and DAC used to simulate a temperature sensor
 *
 * DACB is used by the simulation plant to output a temperature reading of the
 * oven plate. It is set up to output a voltage on pin B2 which is marked as
 * ADC2 on header J2.
 *
 * ADCA is used in the control step and graphical interface to show the current
 * temperature of the oven plate. It is set up to read a voltage on pin A4 which
 * is marked as ADC4 on header J2.
 *
 * ADC2 and ADC4 should be connected together, so that the ADC samples the DAC
 * directly.
 */
void main_init_adc_dac(void)
{
    struct adc_config adc_conf;
    struct adc_channel_config adcch_conf;
    struct dac_config dac_conf;

    /* Set up the DAC for the simulation to output "real" temperature */
    dac_read_configuration(&DACB, &dac_conf);
    dac_set_conversion_parameters(&dac_conf, DAC_REF_BANDGAP,
                                  DAC_ADJ_RIGHT);
    dac_set_active_channel(&dac_conf, DAC_CH0, 0);
    dac_write_configuration(&DACB, &dac_conf);
    dac_enable(&DACB);

    /* Set up the ADC for the controller to read "real" temperature */
    adc_read_configuration(&ADCA, &adc_conf);
    adcch_read_configuration(&ADCA, ADC_CH0, &adcch_conf);
    adc_set_conversion_parameters(&adc_conf, ADC_SIGN_ON, ADC_RES_12,
                                  ADC_REF_BANDGAP);
    adc_set_clock_rate(&adc_conf, 20000UL);
    adc_set_conversion_trigger(&adc_conf, ADC_TRIG_MANUAL, 1, 0);
    adc_write_configuration(&ADCA, &adc_conf);
    adcch_set_input(&adcch_conf, ADCCH_POS_PIN4, ADCCH_NEG_NONE, 1);
    adcch_write_configuration(&ADCA, ADC_CH0, &adcch_conf);
    adc_enable(&ADCA);
    adc_start_conversion(&ADCA, ADC_CH0);

    /* Enable pull-down, so an open circuit can be detected */
    ioport_set_pin_dir(J2_PIN4, IOPORT_DIR_INPUT);
    ioport_set_pin_mode(J2_PIN4, IOPORT_MODE_PULLDOWN);
}
/**
 * \brief Read multiple samples from ADC.
 *
 * Read \c samples samples from the ADC into the buffer \c buffer.
 * If there is no hardware trigger defined (event action) the
 * driver will retrigger the ADC conversion whenever a conversion
 * is complete until \c samples samples has been acquired. To avoid
 * jitter in the sampling frequency using an event trigger is advised.
 *
 * \param[in]  module_inst  Pointer to the ADC software instance struct
 * \param[in]  samples      Number of samples to acquire
 * \param[out] buffer       Buffer to store the ADC samples
 *
 * \return Status of the job start.
 * \retval STATUS_OK        The conversion job was started successfully and is
 *                          in progress
 * \retval STATUS_BUSY      The ADC is already busy with another job
 */
enum status_code adc_read_buffer_job(
    struct adc_module *const module_inst,
    uint16_t *buffer,
    uint16_t samples)
{
    Assert(module_inst);
    Assert(samples);
    Assert(buffer);

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

    module_inst->job_status = STATUS_BUSY;
    module_inst->remaining_conversions = samples;
    module_inst->job_buffer = buffer;

    adc_enable_interrupt(module_inst, ADC_INTERRUPT_RESULT_READY);

    if(module_inst->software_trigger == true) {
        adc_start_conversion(module_inst);
    }

    return STATUS_OK;
}
Exemplo n.º 11
0
/**
 * \brief Test interrupt is getting triggered in various Sleep mode.
 *
 * This function put the device in Idle and Power Save sleep mode and check
 * whether the ADC conversion complete interrupt is executed only in Idle sleep
 * mode.
 * The device will wakeup from power save mode when Timer/Counter2 overflow
 * occur.
 *
 * \param test Current test case.
 */
static void run_sleep_trigger_test(const struct test_case *test)
{
    /* Disable Global interrupt */
    cpu_irq_disable();
    /* Initialize the lock counts */
    sleepmgr_init();
    /* Initialize the ADC */
    adc_initialisation();
    /* Initialize the Timer/Counter2 */
    timer2_initialisation();
    /* Lock Idle Sleep mode */
    sleepmgr_lock_mode(SLEEPMGR_IDLE);
    /* Clear Timer/Counter2 Register */
    TCNT2 = 0;
    /* Wait for TCNT2 register to get updated */
    while (ASSR & (1 << TCN2UB)) {
    }
    /* Start ADC Conversion */
    adc_start_conversion();
    /* Enable Global interrupt */
    cpu_irq_enable();
    /* Go to sleep in the deepest allowed mode */
    sleepmgr_enter_sleep();
    /* Unlock Idle Sleep mode */
    sleepmgr_unlock_mode(SLEEPMGR_IDLE);
    /* Lock Power Save mode */
    sleepmgr_lock_mode(SLEEPMGR_PSAVE);
    /* Clear Timer/Counter2 Register */
    TCNT2 = 0;
    /* Wait for TCNT2 register to get updated */
    while (ASSR & (1 << TCN2UB)) {
    }
    /* Start ADC Conversion */
    adc_start_conversion();
    /* Go to sleep in the deepest allowed mode */
    sleepmgr_enter_sleep();
    /* Disable ADC */
    adc_disable();
    /* Unlock Power Save mode */
    sleepmgr_unlock_mode(SLEEPMGR_PSAVE);

    /* Disable Global interrupt */
    cpu_irq_disable();

    test_assert_true(test, trigger_count == 2,
                     "ADC interrupt trigger failed.");
}
Exemplo n.º 12
0
bool microe_touch_service(LcdTouch_t* Touch)
{
	MicroeTouch_t *MikroeTouch = Touch->UsrData;
	if(!Touch)
		return false;
	if(MikroeTouch->touch_conv_finish == true)
		return true;
	adc_start_conversion(MikroeTouch->Adc);
	while(!MikroeTouch->Adc->EndOfConversion){};
	switch(MikroeTouch->xy_state)
	{
	case 0:
		MikroeTouch->y_data[MikroeTouch->dbidx] = MikroeTouch->Adc->ConvResult[MikroeTouch->AdcChannel_Y];
		break;
	case 1:
		MikroeTouch->x_data[MikroeTouch->dbidx] = MikroeTouch->Adc->ConvResult[MikroeTouch->AdcChannel_X];
		break;
	case 2:
		if(MikroeTouch->Adc->ConvResult[MikroeTouch->AdcChannel_Y] > 1000)
		{
			MikroeTouch->IsTSPress = true;
		}
		MikroeTouch->touch_conv_finish = true;
		MikroeTouch->dbidx = ANALOG_TOUCH_FILTER_LEVEL - 1;
		break;
	default:
		MikroeTouch->xy_state = 0;
		break;
	}
	if(MikroeTouch->dbidx == ANALOG_TOUCH_FILTER_LEVEL - 1)
	{
		MikroeTouch->xy_state++;
		if(MikroeTouch->xy_state >= 3)
			MikroeTouch->xy_state = 0;
		MikroeTouch->dbidx = 0;
		switch(MikroeTouch->xy_state)
		{
		case 0:
			gpio.out(MikroeTouch->DriveB, 1);
			gpio.out(MikroeTouch->DriveA, 0);
			break;
		case 1:
			gpio.out(MikroeTouch->DriveA, 1);
			gpio.out(MikroeTouch->DriveB, 0);
			break;
		case 2:
			gpio.out(MikroeTouch->DriveA, 0);
			gpio.out(MikroeTouch->DriveB, 0);
			break;
		default:
			MikroeTouch->xy_state = 0;
			break;
		}

	}
	else
		MikroeTouch->dbidx++;
	return MikroeTouch->touch_conv_finish;
}
Exemplo n.º 13
0
/**
 * \brief Start the next convertion according to \ref adc_mux_index index
 */
static void app_sampling_start_next_conversion(void)
{
	/* Setup ADC to start next one */
	adcch_set_input(&adcch_conf, adc_conv[adc_mux_index],
			ADCCH_NEG_INTERNAL_GND, 0);
	adcch_write_configuration(&LIGHT_SENSOR_ADC_MODULE, ADC_CH0,
			&adcch_conf);
	adc_start_conversion(&LIGHT_SENSOR_ADC_MODULE, ADC_CH0);
}
Exemplo n.º 14
0
int main(void)
{
	struct adc_config         adc_conf;
	struct adc_channel_config adcch_conf;

	board_init();
	sysclk_init();
	sleepmgr_init();
	irq_initialize_vectors();
	cpu_irq_enable();
	gfx_mono_init();

	// Enable back light of display
	ioport_set_pin_high(LCD_BACKLIGHT_ENABLE_PIN);

	// Initialize configuration structures.
	adc_read_configuration(&ADCA, &adc_conf);
	adcch_read_configuration(&ADCA, ADC_CH0, &adcch_conf);

	/* Configure the ADC module:
	 * - unsigned, 12-bit results
	 * - VCC voltage reference
	 * - 200 kHz maximum clock rate
	 * - manual conversion triggering
	 * - temperature sensor enabled
	 * - callback function
	 */
	adc_set_conversion_parameters(&adc_conf, ADC_SIGN_ON, ADC_RES_12,
			ADC_REF_VCC);
	adc_set_clock_rate(&adc_conf, 200000UL);
	adc_set_conversion_trigger(&adc_conf, ADC_TRIG_MANUAL, 1, 0);
	adc_enable_internal_input(&adc_conf, ADC_INT_TEMPSENSE);

	adc_write_configuration(&ADCA, &adc_conf);
	adc_set_callback(&ADCA, &adc_handler);

	/* Configure ADC channel 0:
	 * - single-ended measurement from temperature sensor
	 * - interrupt flag set on completed conversion
	 * - interrupts disabled
	 */
	adcch_set_input(&adcch_conf, ADCCH_POS_PIN1, ADCCH_NEG_NONE,
			1);
	adcch_set_interrupt_mode(&adcch_conf, ADCCH_MODE_COMPLETE);
	adcch_enable_interrupt(&adcch_conf);

	adcch_write_configuration(&ADCA, ADC_CH0, &adcch_conf);

	// Enable the ADC and start the first conversion.
	adc_enable(&ADCA);
	adc_start_conversion(&ADCA, ADC_CH0);

	do {
		// Sleep until ADC interrupt triggers.
		sleepmgr_enter_sleep();
	} while (1);
}
Exemplo n.º 15
0
int main(void)
{
    struct adc_config         adc_conf;
    struct adc_channel_config adcch_conf;

    board_init();
    sysclk_init();
    sleepmgr_init();
    irq_initialize_vectors();
    cpu_irq_enable();

    // Initialize configuration structures.
    adc_read_configuration(&ADCA, &adc_conf);
    adcch_read_configuration(&ADCA, ADC_CH0, &adcch_conf);

    /* Configure the ADC module:
     * - unsigned, 12-bit results
     * - bandgap (1 V) voltage reference
     * - 200 kHz maximum clock rate
     * - manual conversion triggering
     * - temperature sensor enabled
     * - callback function
     */
    adc_set_conversion_parameters(&adc_conf, ADC_SIGN_OFF, ADC_RES_12,
                                  ADC_REF_BANDGAP);
    adc_set_clock_rate(&adc_conf, 200000UL);
    adc_set_conversion_trigger(&adc_conf, ADC_TRIG_MANUAL, 1, 0);
    adc_enable_internal_input(&adc_conf, ADC_INT_TEMPSENSE);

    adc_write_configuration(&ADCA, &adc_conf);
    adc_set_callback(&ADCA, &adc_handler);

    /* Configure ADC channel 0:
     * - single-ended measurement from temperature sensor
     * - interrupt flag set on completed conversion
     * - interrupts disabled
     */
    adcch_set_input(&adcch_conf, ADCCH_POS_TEMPSENSE, ADCCH_NEG_NONE,
                    1);
    adcch_set_interrupt_mode(&adcch_conf, ADCCH_MODE_COMPLETE);
    adcch_enable_interrupt(&adcch_conf);

    adcch_write_configuration(&ADCA, ADC_CH0, &adcch_conf);

    // Get measurement for 85 degrees C (358 kelvin) from calibration data.
    tempsense = adc_get_calibration_data(ADC_CAL_TEMPSENSE);

    // Enable the ADC and start the first conversion.
    adc_enable(&ADCA);
    adc_start_conversion(&ADCA, ADC_CH0);

    do {
        // Sleep until ADC interrupt triggers.
        sleepmgr_enter_sleep();
    } while (1);
}
Exemplo n.º 16
0
uint16_t getLightSens()
{
	uint16_t result = 0;
	adc_start_conversion(&adc1);
	while(adc_get_status(&adc1) != ADC_STATUS_RESULT_READY);
	adc_read(&adc1, &result);
	result = result * 16;
	adc_clear_status(&adc1, ADC_STATUS_RESULT_READY);

	return result;
}
Exemplo n.º 17
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);
		}
	}
}
Exemplo n.º 18
0
/**
 * \internal
 * \brief Setup Function: ADC window mode test.
 *
 * This function initializes the ADC in window mode.
 * Upper and lower threshold values are provided.
 * It also registers & enables callback for window detection.
 *
 * \param test Current test case.
 */
static void setup_adc_window_mode_test(const struct test_case *test)
{
	enum status_code status = STATUS_ERR_IO;

	interrupt_flag = false;

	/* Set 0.5V DAC output */
	dac_chan_write(&dac_inst, DAC_CHANNEL_0, DAC_VAL_HALF_VOLT);
	delay_ms(1);

	/* Skip test if ADC initialization failed */
	test_assert_true(test, adc_init_success,
			"Skipping test due to failed initialization");

	/* Disable ADC before initialization */
	adc_disable(&adc_inst);
	struct adc_config config;
	adc_get_config_defaults(&config);
	config.positive_input = ADC_POSITIVE_INPUT_PIN2;
	config.negative_input = ADC_NEGATIVE_INPUT_GND;
#if (SAML21)
	config.reference      = ADC_REFERENCE_INTREF;
	config.clock_prescaler = ADC_CLOCK_PRESCALER_DIV16;
#else
	config.reference      = ADC_REFERENCE_INT1V;
#endif
	config.clock_source   = GCLK_GENERATOR_3;
#if !(SAML21)
	config.gain_factor    = ADC_GAIN_FACTOR_1X;
#endif
	config.resolution     = ADC_RESOLUTION_12BIT;
	config.freerunning    = true;
	config.window.window_mode = ADC_WINDOW_MODE_BETWEEN_INVERTED;
	config.window.window_lower_value = (ADC_VAL_DAC_HALF_OUTPUT - ADC_OFFSET);
	config.window.window_upper_value = (ADC_VAL_DAC_HALF_OUTPUT + ADC_OFFSET);

	/* Re-initialize & enable ADC */
	status = adc_init(&adc_inst, ADC, &config);
	test_assert_true(test, status == STATUS_OK,
			"ADC initialization failed");
	status = adc_enable(&adc_inst);
	test_assert_true(test, status == STATUS_OK,
			"ADC enabling failed");

	/* Register and enable window mode callback */
	adc_register_callback(&adc_inst, adc_user_callback,
			ADC_CALLBACK_WINDOW);
	adc_enable_callback(&adc_inst, ADC_CALLBACK_WINDOW);

	/* Start ADC conversion */
	adc_start_conversion(&adc_inst);
}
Exemplo n.º 19
0
int main(void)
{
	system_init();
	delay_init();
	
//! [setup_init]
	configure_adc();
//! [setup_init]

//! [main]
//! [start_conv]
	adc_start_conversion(&adc_instance);
//! [start_conv]

//! [get_res]
	uint16_t result=0;

	configure_console();
	

//! [get_res]

//! [inf_loop]
	while (1) {
		/* Infinite loop */
		//adc_read(&adc_instance, &result);
		do {
		/* Wait for conversion to be done and read out result */
		} while (adc_read(&adc_instance, &result) == STATUS_BUSY);
		printf("The result is %d\n",result);
		uint32_t far = 9.0/5.0*((float)result*.0002441406*6.0/.01)+32.0;
		printf(" The temp is %d", far);
		adc_clear_status(&adc_instance,adc_get_status(&adc_instance));
			adc_start_conversion(&adc_instance);
		delay_ms(500);
	}
//! [inf_loop]
//! [main]
}
Exemplo n.º 20
0
void adc_start(void) {
  // Clear ready flag
  adcComplete = 0;

  // Reset channel
  adcChannel = adcChannelMin;

  // Enable ADC conversion complete interrupt
  ADCSRA |= _BV(ADIE);

  // Start first conversion
  adc_start_conversion(adcChannel);
}
Exemplo n.º 21
0
uint16_t adcReadX()
{
	PORTA_DIR = 0b00110001;
	PORTA_OUT = 0b00010001;
	
	delay_ms(10);
	
	adc_start_conversion(&ADCA, 1);
	delay_ms(10);
	uint16_t pos = adc_get_unsigned_result(&ADCA, 1);
	PORTA_DIR = 0;
	return pos;
}
Exemplo n.º 22
0
/**
 * \brief Captures a values on ADC
 *
 * \return value on ADC pins (mV)
 */
static uint16_t main_adc_input(void)
{
	uint16_t sample;

	adc_start_conversion(&ADCA, ADC_CH0);
	adc_wait_for_interrupt_flag(&ADCA, ADC_CH0);
	sample = adc_get_unsigned_result(&ADCA, ADC_CH0);

	/* Conversion sample to mV :
	 * mV = sample * (VCC / 1.6) / Max. range
	 */
	return ((uint32_t)sample * (3300L * 1000L / 1600L)) / (1 << 12);
}
Exemplo n.º 23
0
/**
 * \brief Timer Counter Overflow interrupt callback function
 *
 * This function is called when an overflow interrupt has occurred on
 * TCC0.
 */
static void tcc0_ovf_interrupt_callback(void)
{
	adc_mux_index=0;
	adc_disable(&EXT_VIN_ADC_MODULE);
	adc_set_conversion_parameters(&adc_conf, ADC_SIGN_OFF, ADC_RES_12
			,adc_conv[adc_mux_index].ref);
	adc_write_configuration(&EXT_VIN_ADC_MODULE, &adc_conf);
	adc_enable(&EXT_VIN_ADC_MODULE);
	adcch_set_input(&adcch_conf, adc_conv[adc_mux_index].in
			, ADCCH_NEG_NONE,1);
	adcch_write_configuration(&EXT_VIN_ADC_MODULE, ADC_CH0, &adcch_conf);
	adc_start_conversion(&EXT_VIN_ADC_MODULE, ADC_CH0);
}
Exemplo n.º 24
0
/**
 * \brief Wrapper function for getting and ADC sample
 *
 * \param   adc_ch which channel to get the ADC samples from
 * /returns        16-bit signed ADC result
 */
static int16_t adc_get_sample(uint8_t adc_ch)
{
	int16_t result = 0;

	adc_start_conversion(&CALIBRATION_ADC, adc_ch);

	adc_wait_for_interrupt_flag(&CALIBRATION_ADC, adc_ch);

	result = adc_get_result(&CALIBRATION_ADC, adc_ch);

	adc_clear_interrupt_flag(&CALIBRATION_ADC, adc_ch);

	return result;
}
Exemplo n.º 25
0
/**
 * \internal
 * \brief Measure differential input MUX combinations on channel
 *
 * Measures a set of input MUX combinations on a single channel, using averaging
 * of the number of samples specified with \ref NUM_AVERAGE_SAMPLES.
 *
 * \pre This function does not configure the ADC, only the ADC channel, and
 * therefore the specified ADC needs to be configured before this function
 * is run.
 *
 * \param adc Pointer to ADC to measure with.
 * \param ch_mask Mask for channel to measure with.
 * \param mux_pos_inputs Pointer to array of positive input MUX settings.
 * \param mux_neg_inputs Pointer to array of negative input MUX settings.
 * \param num_inputs Number of input MUX setting pairs.
 * \param results Pointer to array to store results in.
 * \param gain Gain to use for all measurements.
 *
 * \note The array which \e results points to must have at least \e num_inputs
 * elements.
 */
static void differential_signed_average(ADC_t *adc, uint8_t ch_mask,
		const uint8_t *mux_pos_inputs, const uint8_t *mux_neg_inputs,
		uint8_t num_inputs, int16_t *results, uint8_t gain)
{
	struct adc_channel_config adcch_conf;
	uint8_t input;
	uint8_t i;
	int32_t sum;

	memset(&adcch_conf, 0, sizeof(struct adc_channel_config));

	// Common configuration
	adcch_set_interrupt_mode(&adcch_conf, ADCCH_MODE_COMPLETE);
	adcch_disable_interrupt(&adcch_conf);

	for (input = 0; input < num_inputs; input++) {
		adcch_set_input(&adcch_conf, mux_pos_inputs[input],
				mux_neg_inputs[input], gain);
		adcch_write_configuration(adc, ch_mask, &adcch_conf);

		// Enable and do dummy conversion
		adc_enable(adc);
		adc_start_conversion(adc, ch_mask);
		adc_wait_for_interrupt_flag(adc, ch_mask);

		// Read an average
		sum = 0;
		for (i = 0; i < NUM_AVERAGE_SAMPLES; i++) {
			adc_start_conversion(adc, ch_mask);
			adc_wait_for_interrupt_flag(adc, ch_mask);
			sum += (int16_t)adc_get_result(adc, ch_mask);
		}
		adc_disable(adc);

		results[input] = sum / NUM_AVERAGE_SAMPLES;
	}
}
Exemplo n.º 26
0
/**
 * \brief Callback function for ADC interrupts
 *
 * \param adc Pointer to ADC module.
 * \param channel ADC channel number.
 * \param result Conversion result from ADC channel.
 */
static void adc_handler(ADC_t *adc, uint8_t channel, adc_result_t result)
{
	uint32_t temperature;

	/* Compute current temperature in kelvin, based on the factory
	 * calibration measurement of the temperature sensor. The calibration
	 * has been done at 85 degrees Celsius, which corresponds to 358 kelvin.
	 */
	temperature = (uint32_t)result * 358; 
	temperature /= tempsense;

	// Store temperature in global variable.
	last_temperature = temperature & 0xffff;

	// Start next conversion.
	adc_start_conversion(adc, (1 << channel));
}
Exemplo n.º 27
0
int main(void){
	char xbeebuffer[100];
	int adcSample;

	/**Setup Xbee*/
	PORTD.DIR = 0b00001000;
	PORTF.DIR = 3;

	/**Setup interrupts*/
	PMIC.CTRL |= PMIC_LOLVLEX_bm | PMIC_MEDLVLEX_bm | PMIC_HILVLEX_bm |
		PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm;
	sei();

	USART_InterruptDriver_Initialize(&xbee, &USARTD0, USART_DREINTLVL_LO_gc);
	USART_Format_Set(xbee.usart, USART_CHSIZE_8BIT_gc, USART_PMODE_DISABLED_gc, false);
	USART_RxdInterruptLevel_Set(xbee.usart, USART_RXCINTLVL_HI_gc);
	USART_Baudrate_Set(&USARTD0, 12 , 0);
	USART_Rx_Enable(xbee.usart);
	USART_Tx_Enable(xbee.usart);


	ADC_Ch_InputMode_and_Gain_Config(&ADC_BK.CH0, ADC_CH_INPUTMODE_DIFF_gc, ADC_DRIVER_CH_GAIN_NONE); 	// differential mode, no gain
	ADC_Ch_InputMux_Config(&ADC_BK.CH0, pin, ADC_CH_MUXNEG_PIN1_gc);		

	ADC_Reference_Config(&ADC_BK, ADC_REFSEL_VCC_gc); 		// use Vcc/1.6 as ADC reference

	ADC_ConvMode_and_Resolution_Config(&ADC_BK, ADC_ConvMode_Signed, ADC_RESOLUTION_12BIT_gc);

	ADC_Prescaler_Config(&ADC_BK, ADC_PRESCALER_DIV32_gc);

	while(1){
		if(readdata){
			readdata = 0;
			if(input == 'r'){
				adc_start_conversion(&ADCA, ADC_CH0);
				adc_wait_for_interrupt_flag(&ADCA, ADC_CH0);
				adcSample = adcch_get_signed_result(&ADCA, 0);
				sprintf(xbeebuffer, " %d\n\r", adcSample);
				sendstring(&xbee, xbeebuffer);



			}
		}
	}
}
Exemplo n.º 28
0
void ADC_TIMER_COMPA(void)
{
  //reset the counter
  ADC_TIMER_RESET();
        
  //make sure that data is not read before all channels are sampled
  adcReady   = 0;
        
  //reset the current ADC channel
  adcChannel = 0;
    
  //enable the ADC Conversion Complete interrupt
  ADCSRA    |= _BV(ADIE);
    
  //start the first conversion
  adc_start_conversion(adcChannel);
}
Exemplo n.º 29
0
bool adcCheck()
{
	uint16_t threashold = 500; // around 200 is a sensible value
	
	PORTA_DIR = 0b11000001;
	PORTA_OUT = 0b11000001;
	
	// set pulldown on pin 4
	PORTA.PIN4CTRL = PORT_OPC_PULLDOWN_gc;
	adc_start_conversion(&ADCA, 2); // measure if
	delay_ms(10);
	uint16_t value = adc_get_unsigned_result(&ADCA, 2);
	PORTA.PIN4CTRL = 0;
	
	if(value > threashold) return false;
	return true;
}
Exemplo n.º 30
0
void owltemp_init() {
	struct adc_config         adc_conf;
	struct adc_channel_config adcch_conf;

	// Clear the configuration structures.
	memset(&adc_conf, 0, sizeof(struct adc_config));
	memset(&adcch_conf, 0, sizeof(struct adc_channel_config));

	/* Configure the ADC module:
	 * - unsigned, 12-bit results
	 * - bandgap (1 V) voltage reference
	 * - 200 kHz maximum clock rate
	 * - manual conversion triggering
	 * - temperature sensor enabled
	 * - callback function
	 */
	adc_set_conversion_parameters(&adc_conf, ADC_SIGN_OFF, ADC_RES_12,
			ADC_REF_BANDGAP);
	adc_set_clock_rate(&adc_conf, 200000UL);
	adc_set_conversion_trigger(&adc_conf, ADC_TRIG_MANUAL, 0, 0);
	adc_enable_internal_input(&adc_conf, ADC_INT_TEMPSENSE);

	adc_write_configuration(&ADCA, &adc_conf);
	adc_set_callback(&ADCA, &adc_handler);

	/* Configure ADC channel 0:
	 * - single-ended measurement from temperature sensor
	 * - interrupt flag set on completed conversion
	 * - interrupts disabled
	 */
	adcch_set_input(&adcch_conf, ADCCH_POS_TEMPSENSE, ADCCH_NEG_NONE,
			1);
	adcch_set_interrupt_mode(&adcch_conf, ADCCH_MODE_COMPLETE);
	adcch_enable_interrupt(&adcch_conf);

	adcch_write_configuration(&ADCA, 0, &adcch_conf);

	// Get measurement for 85 degrees C (358 kelvin) from calibration data.
	tempsense = adc_get_calibration_data(ADC_CAL_TEMPSENSE);

	// Enable the ADC and start the first conversion.
	adc_enable(&ADCA);
	adc_start_conversion(&ADCA, ADC_CH0);

}