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);
}
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);
}
Exemple #3
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);

}
Exemple #4
0
void app_sampling_init(void)
{
	/* QDec configuration */
	qdec_get_config_defaults(&qdec_config);
	qdec_config_phase_pins(&qdec_config, &PORTA, 6, false, 500);
	qdec_config_enable_rotary(&qdec_config);
	qdec_config_tc(&qdec_config, &TCC5);
	qdec_config_revolution(&qdec_config, 40);
	qdec_enabled(&qdec_config);

	/* ! ADC module configuration */
	struct adc_config adc_conf;

	/* Configure the ADC module:
	 * - signed, 12-bit results
	 * - VCC reference
	 * - 200 kHz maximum clock rate
	 * - manual conversion triggering
	 * - callback function
	 */
	adc_read_configuration(&LIGHT_SENSOR_ADC_MODULE, &adc_conf);
	adc_set_conversion_parameters(&adc_conf, ADC_SIGN_ON, ADC_RES_12,
			ADC_REF_VCC);
	adc_set_clock_rate(&adc_conf, 200000);
	adc_set_conversion_trigger(&adc_conf, ADC_TRIG_MANUAL, 1, 0);
	adc_write_configuration(&LIGHT_SENSOR_ADC_MODULE, &adc_conf);
	adc_set_callback(&LIGHT_SENSOR_ADC_MODULE, &app_sampling_handler);
	adc_enable(&LIGHT_SENSOR_ADC_MODULE);

	/* Configure ADC A channel 0 for light and NTC sensors.
	 * - differantial measurement (V- linked on internal GND)
	 * - gain x0.5
	 * - interrupt flag set on completed conversion
	 * - interrupts enabled
	 */
	adcch_read_configuration(&LIGHT_SENSOR_ADC_MODULE, ADC_CH0,
			&adcch_conf);
	adcch_set_input(&adcch_conf, LIGHT_SENSOR_ADC_INPUT,
			ADCCH_NEG_INTERNAL_GND, 0);
	adcch_set_interrupt_mode(&adcch_conf, ADCCH_MODE_COMPLETE);
	adcch_enable_interrupt(&adcch_conf);
	adcch_write_configuration(&LIGHT_SENSOR_ADC_MODULE, ADC_CH0,
			&adcch_conf);

	fifo_init(&app_sampling_fifo_desc, app_sampling_fifo_buffer,
			APP_SAMPLING_FIFO_SIZE);
	rtc_set_callback(&app_sampling_start);

	/* Display background */
	gfx_mono_draw_line(DISPLAY_SAMPLING_TEXT_POS_X - 3,
			0,
			DISPLAY_SAMPLING_TEXT_POS_X - 3,
			32,
			GFX_PIXEL_SET);
	app_sampling_display_rate();
	gfx_mono_draw_string(DISPLAY_LIGHT_TEXT,
			DISPLAY_LIGHT_TEXT_POS_X,
			DISPLAY_LIGHT_TEXT_POS_Y,
			&sysfont);
	gfx_mono_draw_filled_rect(
			DISPLAY_LIGHT_PROBAR_START_POS_X,
			DISPLAY_LIGHT_PROBAR_START_POS_Y,
			DISPLAY_LIGHT_PROBAR_START_SIZE_X,
			DISPLAY_LIGHT_PROBAR_START_SIZE_Y,
			GFX_PIXEL_SET);
	gfx_mono_draw_filled_rect(
			DISPLAY_LIGHT_PROBAR_STOP_POS_X,
			DISPLAY_LIGHT_PROBAR_STOP_POS_Y,
			DISPLAY_LIGHT_PROBAR_STOP_SIZE_X,
			DISPLAY_LIGHT_PROBAR_STOP_SIZE_Y,
			GFX_PIXEL_SET);

	/* Start a RTC alarm immediatly */
	rtc_set_alarm_relative(0);
}
Exemple #5
0
/**
 * \brief Show menu for error insertion and handle user's selection.
 *
 * This function changes device configurations and does some hacks to make
 * the device behave incorrectly.
 *
 * The menu entries are
 *   - Change clock frequency: Changes the peripheral clock divider, simulating
 *     that the clock system has malfunctioned. This should be detected by the
 *     Class B frequency consistency test.
 *
 *   - Mess with test timer: Changes how often periodic tests are performed,
 *     simulating an error with an interrupt timer. This should be detected by
 *     the Class B interrupt monitor.
 *
 *   - Change a Flash section: Changes the string for the menu title stored in
 *     program memory to "Out of cheese", simulating Flash memory corruption.
 *     This can be changed back by selecting the menu item again. This should be
 *     detected by the Class B Flash CRC test.
 *
 *   - Scramble SRAM section: Starts a continuous DMA transfer in the background
 *     to a memory location, simulating transient SRAM corruption. This should
 *     be detected by the periodic and power-on Class B SRAM test.
 *
 *   - Enter infinite loop: Simulates a runaway program counter by looping
 *     forever. This should be detected by the watchdog timer system which is
 *     tested on device power-up.
 *
 *   - Change ADC reference: Enables a callback function for the ADC, which will
 *     change the voltage reference after the next completed conversion. This
 *     will cause the analog IO test to fail when user turns up the power to the
 *     plate.
 */
void oven_classb_error_insertion(void)
{
	uint8_t menu_status;
	struct keyboard_event input;
	struct adc_channel_config adcch_conf;

	/* Initialize menu system */
	gfx_mono_menu_init(&error_menu);

	/* Wait for user to select something in the menu system */
	do {
		do {
			keyboard_get_key_state(&input);
			oven_wdt_periodic_reset();
			/* Wait for key release */
		} while (input.type != KEYBOARD_RELEASE);

		/* Send key to menu system */
		menu_status = gfx_mono_menu_process_key(&error_menu,
				input.keycode);

		oven_wdt_periodic_reset();
	} while (menu_status == GFX_MONO_MENU_EVENT_IDLE);

	/* Handle the user's selection */
	switch (menu_status) {
	case 0:
		/* Change cpu frequency by modifying the prescalers */
		sysclk_set_prescalers(CLK_PSADIV_4_gc, CLK_PSBCDIV_1_1_gc);
		break;

	case 1:
		/* Change timing of the periodic temperature tests */
		OVEN_PERIODIC_TEMPTEST_TC.CTRLA = TC_CLKSEL_DIV256_gc;
		break;

	case 2:
		/* Change flash section. */
		oven_classb_flash_corrupter();
		break;

	case 3:
		/* Disrupt SRAM by setting up the DMA to write to a location on
		 * the heap, triggered by the class B frequency monitor timer
		 */
		PR.PRGEN &= ~PR_DMA_bm;
		DMA.CTRL |= DMA_ENABLE_bm;
		DMA.CH0.TRIGSRC = DMA_CH_TRIGSRC_TCD1_CCA_gc;
		/* Address of Timer D1 CNT base is 0x0960. */
		DMA.CH0.SRCADDR0 = 0x60;
		DMA.CH0.SRCADDR1 = 0x09;
		DMA.CH0.SRCADDR2 = 0x00;

		DMA.CH0.DESTADDR0 = ((uint16_t)&variable_for_sram_error) & 0xFF;
		DMA.CH0.DESTADDR1 = (((uint16_t)&variable_for_sram_error) >> 8)
				& 0xFF;
		DMA.CH0.DESTADDR2 = 0x00;

		DMA.CH0.CTRLA = DMA_CH_BURSTLEN_2BYTE_gc | DMA_CH_REPEAT_bm
				| DMA_CH_ENABLE_bm;
		break;

	case 4:
		/* Enter infinite loop */
		while (1) {
		}
		break;

	case 5:
		/* Set up ADC channel interrupt */
		adc_set_callback(&ADCA, adc_foul_callback);
		adcch_read_configuration(&ADCA, ADC_CH0, &adcch_conf);
		adcch_enable_interrupt(&adcch_conf);
		adcch_write_configuration(&ADCA, ADC_CH0, &adcch_conf);

		adcch_read_configuration(&ADCA, ADC_CH2, &adcch_conf);
		adcch_enable_interrupt(&adcch_conf);
		adcch_write_configuration(&ADCA, ADC_CH2, &adcch_conf);
		break;

	case 6:
		/* Back */
		break;

	case GFX_MONO_MENU_EVENT_EXIT:
		/* Fall through to default */
	default:
		/* Nothing, go back. */
		break;
	}
}
Exemple #6
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
	 */
	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_write_configuration(&ADCA, &adc_conf);

	/* Configure ADC channel 0:
	 * - single-ended measurement from configured input pin
	 * - interrupt flag set on completed conversion
	 */
	adcch_set_input(&adcch_conf, INPUT_PIN, ADCCH_NEG_NONE,
			1);
	adcch_set_interrupt_mode(&adcch_conf, ADCCH_MODE_COMPLETE);
	adcch_disable_interrupt(&adcch_conf);

	adcch_write_configuration(&ADCA, ADC_CH0, &adcch_conf);

	// Enable the ADC and do one dummy conversion.
	adc_enable(&ADCA);
	adc_start_conversion(&ADCA, ADC_CH0);
	adc_wait_for_interrupt_flag(&ADCA, ADC_CH0);

	// Light up LED 1, wait for button press.
	ioport_set_pin_low(LED1_PIN);
	wait_for_button();

	// Perform oversampling of offset.
	cal_data.offset = get_mean_sample_value();

	// Light up LED 2, wait for button press.
	ioport_set_pin_low(LED2_PIN);
	wait_for_button();

	// Perform oversampling of 0.9 V for gain calibration.
	cal_data.gain = get_mean_sample_value() - cal_data.offset;

	// Turn off LEDs.
	ioport_set_pin_high(LED1_PIN);
	ioport_set_pin_high(LED2_PIN);

	// Enable interrupts on ADC channel, then trigger first conversion.
	adcch_enable_interrupt(&adcch_conf);
	adcch_write_configuration(&ADCA, ADC_CH0, &adcch_conf);
	adc_start_conversion(&ADCA, ADC_CH0);

	do {
		// Sleep until ADC interrupt triggers.
		sleepmgr_enter_sleep();
	} while (1);
}
/**
 * \brief This function processes sampled ADC values and calculate
 *        the oversampling result
 *  - Offset error compensation is applied on accumulated ADC value
 *  - After, scaling is done with scaled factor.
 *  - Finally, Analog value at ADC input pin is calculated
 *  - Reset all variable used in ADC ISR and enable ADC interrupt to start
 *    next oversampling Process.
 */
void adc_oversampled(void)
{
	/* ***********Processing and display of oversampled
	 * Input*************
	 **/

	/* Assign sign as +ve (as zero) in default for Rrw ADC count display */
	uint8_t sign_flag = 0;

	/* Offset error Compensation for entire number of samples */
	adc_result_accum_processed = adc_result_accumulator - adc_offset;

	/* Gain error Compensation for entire number of samples */
	adc_result_accum_processed = (adc_result_accum_processed *
			ADC_GAIN_ERROR_FACTOR) >> 16;

	/* Scale the accumulated result to get over sampled Result */
	adc_result_accum_processed = adc_result_accum_processed >>
			ADC_OVER_SAMP_SCALING_FACTOR;

	/* Calculate the analog input voltage value
	 * - Input Analog value = (ADC_Count * Reference
	 * Volt)/(2^adcresolution))
	 */
	v_input = (adc_result_accum_processed) *
			(ADC_OVER_SAMP_REF_VOLT_IN_MICRO);

	v_input = v_input / ADC_OVER_SAMP_MAX_COUNT;

	/* If input is negative, assign sign for display and use absolute value
	 */
	if (v_input < 0) {
		v_input = abs(v_input);
		v_input_ascii_buf[0] = '-';
	} else {
		v_input_ascii_buf[0] = '+';
	}

	/* Convert calculated analog value to ASCII for display */
	convert_to_ascii(&v_input_ascii_buf[ASCII_BUFFER_SIZE - 1], v_input);

	/* Display the result on LCD display */
	gfx_mono_draw_string(v_input_ascii_buf, 0, 10, &sysfont);

	/* If ADC count is negative, assign sign for display and use absolute
	 * value */
	if (adc_result_accum_processed < 0) {
		adc_result_accum_processed = abs(adc_result_accum_processed);
		sign_flag = 1;
	} else {
		sign_flag = 0;
	}

	/* Display oversampled raw ADC count on LCD display */
	display_adccount((int64_t)adc_result_accum_processed, (uint8_t)42,
			sign_flag );

	/* ***********Processing and display of Single Sampled
	 * Input*************
	 **/

	/* Offset error compensation for one sample */
	adc_result_one_sample_processed = adc_result_one_sample -
			adc_offset_one_sample;

	/* Gain error compensation for one sample */
	adc_result_one_sample_processed = (adc_result_one_sample_processed *
			ADC_GAIN_ERROR_FACTOR) >> 16;

	/* Calculate the analog input voltage value without oversampling
	 * - Input analog value = (ADC_Count * Reference
	 * Volt)/(2^adcresolution))
	 */
	v_input_one_sample = (adc_result_one_sample_processed) *
			(ADC_OVER_SAMP_REF_VOLT_IN_MICRO);

	v_input_one_sample = v_input_one_sample / ADC_NO_OVER_SAMP_MAX_COUNT;

	/* If input is negative, assign sign for display and use absolute value
	 */
	if (v_input_one_sample < 0) {
		v_input_one_sample = abs(v_input_one_sample);
		v_input_ascii_buf[0] = '-';
	} else {
		v_input_ascii_buf[0] = '+';
	}

	/* Convert calculated analog value to ASCII for display(no oversampling)
	 */
	convert_to_ascii(&v_input_ascii_buf[ASCII_BUFFER_SIZE - 1],
			v_input_one_sample);

	/* Display the result on LCD display(no oversampling) */
	gfx_mono_draw_string(v_input_ascii_buf, 75, 10, &sysfont);

	/* If ADC count is negative, assign sign for display and use absolute
	 * value */
	if (adc_result_one_sample_processed < 0) {
		adc_result_one_sample_processed = abs(
				adc_result_one_sample_processed);
		sign_flag = 1;
	} else {
		sign_flag = 0;
	}

	/* Display oversampled raw ADC count on LCD display */
	display_adccount((int64_t)adc_result_one_sample_processed,
			(uint8_t)117, sign_flag );

	/*Reset ADC_result accumulator value and ADC_sample count to zero
	 * for next oversampling process
	 */
	adc_result_accumulator = 0;
	adc_result_accum_processed = 0;
	adc_samplecount = 0;

	adc_result_one_sample = 0;
	adc_result_one_sample_processed = 0;

	/* Configure conversion complete interrupt for  ADCB-CH0 to re-start
	 * over sampling
	 */
	adcch_set_interrupt_mode(&adc_ch_conf, ADCCH_MODE_COMPLETE);
	adcch_enable_interrupt(&adc_ch_conf);
	adcch_write_configuration(&ADCB, ADC_CH0, &adc_ch_conf);
}
/**
 * \brief This function initialize the ADCB,gets ADCB-CH0 offset and configure
 *        ADCB-CH0 for oversampling
 *  - ADCB-CH0 is configured in 12bit, signed differential mode without gain
 *  - To read ADC offset, ADCB-Pin3(PB3) used as both +ve and -ve input
 *  - After reading ADC offset,to start oversampling,ADCB +ve and -ve input
 *    are configured
 */
void init_adc(void)
{
	/* Initialize configuration structures */
	adc_read_configuration(&ADCB, &adc_conf);
	adcch_read_configuration(&ADCB, ADC_CH0, &adc_ch_conf);

	/* Configure the ADCB module:
	 * - Signed, 12-bit resolution
	 * - External reference on AREFB pin.
	 * - 250 KSPS ADC clock rate
	 * - Manual conversion triggering
	 * - Callback function
	 */
	adc_set_conversion_parameters(&adc_conf, ADC_SIGN_ON, ADC_RES_12,
			ADC_REF_AREFB);
	adc_set_clock_rate(&adc_conf, 250000UL);
	adc_set_conversion_trigger(&adc_conf, ADC_TRIG_MANUAL, 1, 0);
	adc_write_configuration(&ADCB, &adc_conf);
	adc_set_callback(&ADCB, &adc_handler);

	/* Configure ADC B channel 0 for offset calculation
	 * - Differential mode without gain
	 * - Selected Pin3 (PB3) as +ve and -ve input for offset calculation
	 */
	adcch_set_input(&adc_ch_conf, ADCCH_POS_PIN3, ADCCH_NEG_PIN3, 1);
	adcch_write_configuration(&ADCB, ADC_CH0, &adc_ch_conf);

	/* Enable ADCB */
	adc_enable(&ADCB);

	/* Get ADC offset in to ADC_Offset variable and disable ADC */
	adc_offset_one_sample = adc_offset_get_signed();

	/* Find ADC_Offset for for total number of samples */
	adc_offset = adc_offset_one_sample * ADC_OVER_SAMPLED_NUMBER;

	/* Disable ADC to configure for oversampling */
	adc_disable(&ADCB);

	/* Configure the ADCB module for oversampling:
	 * - Signed, 12-bit resolution
	 * - External reference on AREFB pin.
	 * - 250 KSPS ADC clock rate
	 * - Free running mode on Channel0 ( First Channel)
	 */

	adc_set_conversion_trigger(&adc_conf, ADC_TRIG_FREERUN_SWEEP, 1, 0);
	adc_write_configuration(&ADCB, &adc_conf);

	/* Configure ADC B channel 0 for oversampling input
	 * - Differential mode without gain
	 * - Selected Pin1 (PB1) as +ve and Pin2 (PB2) as-ve input
	 * - Conversion complete interrupt
	 */
	adcch_set_input(&adc_ch_conf, ADC_OVER_SAMP_POSTIVE_PIN,
			ADC_OVER_SAMP_NEGATIVE_PIN, 1);
	adcch_set_interrupt_mode(&adc_ch_conf, ADCCH_MODE_COMPLETE);
	adcch_enable_interrupt(&adc_ch_conf);
	adcch_write_configuration(&ADCB, ADC_CH0, &adc_ch_conf);

	/* Enable ADCB */
	adc_enable(&ADCB);
}