示例#1
0
文件: adc.c 项目: hiccchen/d-gitku
/**
 ****************************************************************************************
 * @brief  Read ADC conversion result
 * @param[in]    S          ADC read configuration, contains work mode, trigger source, start/end channel
 * @param[in]    buf        ADC result buffer
 * @param[in]    samples    Sample number
 * @param[in]    callback   callback after all the samples conversion finish
 * @description
 *  This function is used to read ADC specified channel conversion result.
 * @note
 *  When use scaning mode, only can select first 6 channel (AIN0,AIN1,AIN2,AIN3,AIN01,AIN23)
 *****************************************************************************************
 */
void adc_read(const adc_read_configuration *S, int16_t *buf, uint32_t samples, void (*callback)(void))
{
    uint32_t reg;
    uint32_t mask;

    adc_env.mode = S->mode;
    adc_env.trig_src = S->trig_src;
    adc_env.start_ch = S->start_ch;
    adc_env.end_ch = S->end_ch;
    adc_env.bufptr = buf;
    adc_env.samples = samples;
    adc_env.callback = callback;
    

    // Busrt scan mode, need read all of the channel after once trigger
    if (S->mode == SINGLE_SCAN_MOD) {
        scan_ch_num = S->end_ch - S->start_ch + 1;
    }
    else {
        scan_ch_num = 1;
    }

#if (CONFIG_ADC_ENABLE_INTERRUPT==FALSE) && (ADC_DMA_EN==TRUE)
    dma_init();
    // samples*2 <= 0x7FF
    dma_rx(DMA_TRANS_HALF_WORD, DMA_ADC, (uint32_t)buf, samples*2, callback);
#endif

    mask = ADC_MASK_SCAN_CH_START
         | ADC_MASK_SCAN_CH_END
         | ADC_MASK_SCAN_INTV
         | ADC_MASK_SCAN_EN
         | ADC_MASK_SINGLE_EN
         | ADC_MASK_START_SEL
         | ADC_MASK_SFT_START
         | ADC_MASK_POW_UP_DLY
         | ADC_MASK_POW_DN_CTRL
         | ADC_MASK_ADC_EN;

    reg = (S->start_ch << ADC_POS_SCAN_CH_START)    // set adc channel, or set scan start channel
        | (S->end_ch << ADC_POS_SCAN_CH_END)        // set scan end channel
        | (0x03 << ADC_POS_SCAN_INTV)               // should not be set to 0 at single mode
        | (S->trig_src << ADC_POS_START_SEL)        // select ADC trigger source
        | (0x3F << ADC_POS_POW_UP_DLY)              // power up delay
        | ADC_MASK_POW_DN_CTRL                      // enable power down control by hardware, only work in single mode
        | ADC_MASK_ADC_EN;                          // enable ADC

    if ((S->mode == SINGLE_SCAN_MOD) || (S->mode == SINGLE_MOD)) {  // default is continue
        reg |= ADC_MASK_SINGLE_EN;                                  // single mode enable
    }
    if ((S->mode == SINGLE_SCAN_MOD) || (S->mode == CONTINUE_SCAN_MOD)) {   // default is not scan
        reg |= ADC_MASK_SCAN_EN;                                            // scan mode enable
    }

    adc_adc_SetADC0WithMask(QN_ADC, mask, reg);
    if (adc_env.trig_src == ADC_TRIG_SOFT) {
        // SFT_START 0->1 trigger ADC conversion
        adc_adc_SetADC0WithMask(QN_ADC, ADC_MASK_SFT_START, MASK_ENABLE);
    }

#if CONFIG_ADC_ENABLE_INTERRUPT==TRUE
    dev_prevent_sleep(PM_MASK_ADC_ACTIVE_BIT);
#elif (CONFIG_ADC_ENABLE_INTERRUPT==FALSE) && (ADC_DMA_EN==FALSE)

    // polling
    while(samples > 0)
    {
        for (int i = 0; ((i < scan_ch_num)&&(samples)); i++) {
            while(!(adc_adc_GetSR(QN_ADC) & ADC_MASK_DAT_RDY_IF));
            *buf++ = adc_adc_GetDATA(QN_ADC);
            samples--;
        }

        // Single mode enable, software trigger
        if ( (samples) && (adc_env.trig_src == ADC_TRIG_SOFT) && ((S->mode == SINGLE_SCAN_MOD)||(S->mode == SINGLE_MOD))) {
            // SFT_START 0->1 trigger ADC conversion
            adc_adc_SetADC0WithMask(QN_ADC, ADC_MASK_SFT_START, MASK_DISABLE);
            adc_adc_SetADC0WithMask(QN_ADC, ADC_MASK_SFT_START, MASK_ENABLE);
        }
    }

    // disable ADC
    adc_enable(MASK_DISABLE);
    adc_clean_fifo();

#if ADC_CALLBACK_EN==TRUE
    if (callback != NULL)
    {
        callback();
    }
#endif
#endif
}
示例#2
0
/*!
 *  \brief Get the current potentiometer value.
 *
 *  \param pxLog a Log structure.
 *
 *  \return true upon success, false if error.
 */
bool b_potentiometer_get_value( xLogDef *pxLog )
{
   int i_current_val;


   /* enable channel for sensor */
   adc_enable( adc, ADC_POTENTIOMETER_CHANNEL );
   /* start conversion */
   adc_start( adc );
   /* get value for sensor */
   i_current_val = adc_get_value( adc, ADC_POTENTIOMETER_CHANNEL ) * 100 / ADC_MAX_VALUE;
   /* Disable channel for sensor */
   adc_disable( adc, ADC_POTENTIOMETER_CHANNEL );

   // Alloc memory for the log string.
   pxLog->pcStringLog = pvPortMalloc( 16*sizeof( char ) );
   if( NULL == pxLog->pcStringLog )
   {
      return( false );
   }
   pxLog->pfFreeStringLog = vPortFree; // Because pvPortMalloc() was used to
                                       // alloc the log string.

   // Build the log string.
   if( i_current_val <= ul_pot_min )
   {
      sprintf( pxLog->pcStringLog, "%3d%% | min", i_current_val );
      // if alarms have to be checked and no alarm for min was pending
      if (( b_pot_alarm == pdTRUE ) && ( b_pot_alarm_min == pdFALSE ))
      {
        // alarm has been taken into account,
        // don't reenter this test before leaving min area
        b_pot_alarm_min = pdTRUE;
        // allow alarm if max is reached
        b_pot_alarm_max = pdFALSE;
        // post alarm to SMTP task
        v_SMTP_Post("Min Potentiometer Alarm", NULL);
      }
   }
   else if( i_current_val >= ul_pot_max )
   {
      sprintf( pxLog->pcStringLog, "%3d%% | max", i_current_val );
      // if alarms have to be checked and no alarm for max was pending
      if (( b_pot_alarm == pdTRUE ) && ( b_pot_alarm_max == pdFALSE ))
      {
        // alarm has been taken into account,
        // don't reenter this test before leaving max area
        b_pot_alarm_max = pdTRUE;
        // allow alarm if min is reached
        b_pot_alarm_min = pdFALSE;
        // post alarm to SMTP task
        v_SMTP_Post("Max Potentiometer Alarm", NULL);
      }
   }
   else
   {
      sprintf( pxLog->pcStringLog, "%3d%%", i_current_val );
      // if alarms have to be checked
      if ( b_pot_alarm == pdTRUE )
      {
        // no alarm is pending
        b_pot_alarm_max = pdFALSE;
        b_pot_alarm_min = pdFALSE;
      }
   }

   return( true );
}
示例#3
0
/**
 * \brief Example entry point.
 *
 * \return Unused (ANSI-C compatibility).
 */
int main(void)
{
	uint8_t c_choice;
	int16_t s_adc_value;
	int16_t s_dac_value;
	int16_t s_threshold = 0;
	float f_dac_data;
	uint32_t ul_dac_data;

	/* Initialize the SAM system. */
	sysclk_init();
	board_init();

	configure_console();

	/* Output example information. */
	puts(STRING_HEADER);

	/* Initialize threshold. */
	gs_us_low_threshold = 1023;
	gs_us_high_threshold = 4095;

	struct adc_config adc_cfg = {
		/* System clock division factor is 16 */
		.prescal = ADC_PRESCAL_DIV16,
		/* The APB clock is used */
		.clksel = ADC_CLKSEL_APBCLK,
		/* Max speed is 150K */
		.speed = ADC_SPEED_150K,
		/* ADC Reference voltage is internal 1.0V */
		.refsel = ADC_REFSEL_0,
		/* Enables the Startup time */
		.start_up = CONFIG_ADC_STARTUP
	};
	struct adc_seq_config adc_seq_cfg = {
		/* Select Vref for shift cycle */
		.zoomrange = ADC_ZOOMRANGE_0,
		/* Pad Ground */
		.muxneg = ADC_MUXNEG_1,
		/* DAC Internal */
		.muxpos = ADC_MUXPOS_3,
		/* Enables the internal voltage sources */
		.internal = ADC_INTERNAL_3,
		/* Disables the ADC gain error reduction */
		.gcomp = ADC_GCOMP_DIS,
		/* Disables the HWLA mode */
		.hwla = ADC_HWLA_DIS,
		/* 12-bits resolution */
		.res = ADC_RES_12_BIT,
		/* Enables the single-ended mode */
		.bipolar = ADC_BIPOLAR_SINGLEENDED
	};
	struct adc_ch_config adc_ch_cfg = {
		.seq_cfg = &adc_seq_cfg,
		/* Internal Timer Max Counter */
		.internal_timer_max_count = 60,
		/* Window monitor mode is off */
		.window_mode = ADC_WM_MODE_3,
		/* The equivalent voltage value is 1023 * VOLT_REF / 4095 = 250mv. */
		.low_threshold = gs_us_low_threshold,
		/* The equivalent voltage value is 4095 * VOLT_REF / 4095 = 1000mv. */
		.high_threshold = gs_us_high_threshold,
	};

	start_dac();

	if(adc_init(&g_adc_inst, ADCIFE, &adc_cfg) != STATUS_OK) {
		puts("-F- ADC Init Fail!\n\r");
		while(1);
	}
	if(adc_enable(&g_adc_inst) != STATUS_OK) {
		puts("-F- ADC Enable Fail!\n\r");
		while(1);
	}
	adc_ch_set_config(&g_adc_inst, &adc_ch_cfg);
	adc_configure_trigger(&g_adc_inst, ADC_TRIG_CON);
	adc_configure_gain(&g_adc_inst, ADC_GAIN_1X);
	adc_set_callback(&g_adc_inst, ADC_WINDOW_MONITOR, adcife_wm_handler,
			ADCIFE_IRQn, 1);

	/* Display main menu. */
	display_menu();

	while (1) {

		scanf("%c", (char *)&c_choice);
		printf("%c\r\n", c_choice);
		switch (c_choice) {
		case '0':
			adc_disable_interrupt(&g_adc_inst, ADC_WINDOW_MONITOR);
			printf("DAC output is set to(mv) from 0mv to %dmv: ",
					(int32_t)VOLT_REF);
			s_dac_value = get_voltage();
			puts("\r");
			f_dac_data = (float)s_dac_value * DACC_MAX_DATA / VDDANA;
			ul_dac_data = f_to_int(f_dac_data);
			if (s_dac_value >= 0) {
				dacc_write_conversion_data(DACC, ul_dac_data);
			}
			delay_ms(100);
			adc_clear_status(&g_adc_inst, ADCIFE_SCR_WM);
			adc_enable_interrupt(&g_adc_inst, ADC_WINDOW_MONITOR);
			break;

		case '1':
			adc_disable_interrupt(&g_adc_inst, ADC_WINDOW_MONITOR);
			printf("Low threshold is set to(mv) from 0mv to %dmv: ",
					(int32_t)VOLT_REF);
			s_threshold = get_voltage();
			puts("\r");
			if (s_threshold >= 0) {
				s_adc_value = s_threshold * MAX_DIGITAL /
						VOLT_REF;
				adc_configure_wm_threshold(&g_adc_inst,
						s_adc_value,
						gs_us_high_threshold);
				/* Renew low threshold. */
				gs_us_low_threshold = s_adc_value;
				float f_low_threshold =
						(float)gs_us_low_threshold *
						VOLT_REF / MAX_DIGITAL;
				uint32_t ul_low_threshold =
						f_to_int(f_low_threshold);
				printf("Setting low threshold to %u mv (reg value to 0x%x ~%d%%)\n\r",
						ul_low_threshold, gs_us_low_threshold,
						gs_us_low_threshold * 100 / MAX_DIGITAL);
			}
			adc_clear_status(&g_adc_inst, ADCIFE_SCR_WM);
			adc_enable_interrupt(&g_adc_inst, ADC_WINDOW_MONITOR);
			break;

		case '2':
			adc_disable_interrupt(&g_adc_inst, ADC_WINDOW_MONITOR);
			printf("High threshold is set to(mv)from 0mv to %dmv:",
					(int32_t)VOLT_REF);
			s_threshold = get_voltage();
			puts("\r");
			if (s_threshold >= 0) {
				s_adc_value = s_threshold * MAX_DIGITAL /
						VOLT_REF;
				adc_configure_wm_threshold(&g_adc_inst,
						gs_us_low_threshold,
						s_adc_value);
				/* Renew high threshold. */
				gs_us_high_threshold = s_adc_value;
				float f_high_threshold =
						(float)gs_us_high_threshold *
						VOLT_REF / MAX_DIGITAL;
				uint32_t ul_high_threshold =
						f_to_int(f_high_threshold);
				printf("Setting high threshold to %u mv (reg value to 0x%x ~%d%%)\n\r",
						ul_high_threshold, gs_us_high_threshold,
						gs_us_high_threshold * 100 / MAX_DIGITAL);
			}
			adc_clear_status(&g_adc_inst, ADCIFE_SCR_WM);
			adc_enable_interrupt(&g_adc_inst, ADC_WINDOW_MONITOR);
			break;

		case '3':
			adc_disable_interrupt(&g_adc_inst, ADC_WINDOW_MONITOR);
			puts("-a. Above low threshold.\n\r"
					"-b. Below high threshold.\n\r"
					"-c. In the comparison window.\n\r"
					"-d. Out of the comparison window.\n\r"
					"-q. Quit the setting.\r");
			c_choice = get_wm_mode();
			adc_configure_wm_mode(&g_adc_inst, c_choice);
			printf("Comparison mode is %c.\n\r", 'a' + c_choice - 1);
			adc_clear_status(&g_adc_inst, ADCIFE_SCR_WM);
			adc_enable_interrupt(&g_adc_inst, ADC_WINDOW_MONITOR);
			break;

		case 'm':
			display_menu();
			break;

		case 'i':
			display_info();
			adc_clear_status(&g_adc_inst, ADCIFE_SCR_WM);
			adc_enable_interrupt(&g_adc_inst, ADC_WINDOW_MONITOR);
			break;
		}
		puts("Press \'m\' or \'M\' to display the main menu again!\r");
	}
}
示例#4
0
文件: adc.c 项目: hiccchen/d-gitku
 /**
 ****************************************************************************************
 * @brief ADC interrupt handler
 ****************************************************************************************
 */
void ADC_IRQHandler(void)
{
    uint32_t status, data;

    status = adc_adc_GetSR(QN_ADC);
    if (status & ADC_MASK_DAT_RDY_IF)
    {
        while (adc_adc_GetSR(QN_ADC) & ADC_MASK_DAT_RDY_IF)
        {
            /* clear interrupt flag by read data */
            data = adc_adc_GetDATA(QN_ADC);
            if (adc_env.samples > 0) {
                *adc_env.bufptr++ = data;
                adc_env.samples--;

                if (adc_env.samples == 0) {
                    adc_enable(MASK_DISABLE); // disable ADC
                    adc_clean_fifo();
                    NVIC_ClearPendingIRQ(ADC_IRQn);

#if ADC_CALLBACK_EN==TRUE
                    if (adc_env.callback != NULL)
                    {
                        adc_env.callback();
                    }
#endif
                }
                else {

                    // single mode enable, software trigger
                    if ((adc_env.trig_src == ADC_TRIG_SOFT) && ((adc_env.mode == SINGLE_SCAN_MOD)||(adc_env.mode == SINGLE_MOD))) {

                        scan_ch_num--;
                        if (scan_ch_num == 0) {

                            // SFT_START 0->1 trigger ADC conversion
                            adc_adc_SetADC0WithMask(QN_ADC, ADC_MASK_SFT_START, MASK_DISABLE);
                            adc_adc_SetADC0WithMask(QN_ADC, ADC_MASK_SFT_START, MASK_ENABLE);

                            // restore scan_ch_num
                            if (adc_env.mode == SINGLE_SCAN_MOD) {
                                scan_ch_num = adc_env.end_ch - adc_env.start_ch + 1;
                            }
                            else {
                                scan_ch_num = 1;
                            }
                        }
                    }
                }
            }
        }
    }

    if (status & ADC_MASK_FIFO_OF_IF)
    {
        adc_clean_fifo();

        /* clear interrupt flag */
        adc_adc_ClrSR(QN_ADC, ADC_MASK_FIFO_OF_IF);
    }


    if (status & ADC_MASK_WCMP_IF)
    {
        /* clear interrupt flag */
        adc_adc_ClrSR(QN_ADC, ADC_MASK_WCMP_IF);

#if ADC_WCMP_CALLBACK_EN==TRUE
        if (adc_env.wcmp_callback != NULL)
        {
            adc_env.wcmp_callback();
        }
#endif
    }
}
示例#5
0
void alphasense_adc_getValue( void )
{
	//ALPHASENSE_STATS * const ps = &g_internal;
	struct adc_config adc_conf;
	struct adc_channel_config adcch_conf;
	uint8_t inputgain = 1;//, elements = 20;
	//char szBUF[64];
	
	// DISABLE jtag - it locks the upper 4 pins of PORT B
	CCP       = CCP_IOREG_gc;    // Secret handshake
	MCU.MCUCR = 0b00000001;
	
	PORTB.PIN0CTRL = PORT_OPC_TOTEM_gc; // Auxiliary Electrode
	PORTB.PIN2CTRL = PORT_OPC_TOTEM_gc; // Working Electrode
	PORTB.PIN6CTRL = PORT_OPC_TOTEM_gc; // GND x offset
	
	adc_read_configuration(&ALPHASENSE_ADC, &adc_conf);
	adcch_read_configuration(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH, &adcch_conf);
	
	adc_set_conversion_parameters(&adc_conf, ADC_SIGN_OFF, ADC_RES_12, ADC_REF_VCC);
	adc_set_conversion_trigger(&adc_conf, ADC_TRIG_MANUAL, 1, 0);
	adc_set_clock_rate(&adc_conf, 200000UL);
	adc_write_configuration(&ALPHASENSE_ADC, &adc_conf);
	
	
	adcch_set_input(&adcch_conf, ADCCH_POS_PIN6, ADCCH_NEG_NONE, inputgain);
	adcch_write_configuration(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH, &adcch_conf);
	adc_enable(&ALPHASENSE_ADC);
	adc_start_conversion(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH);
	adc_wait_for_interrupt_flag(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH);
	adc_start_conversion(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH);
	adc_wait_for_interrupt_flag(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH);
	const int16_t off = adc_get_result(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH);
	adc_disable(&ALPHASENSE_ADC);
	//sprintf_P(szBUF,PSTR("Offset: %u\t"),off);
	//debug_string(NORMAL,szBUF,false);
	
	
	//adcch_set_input(&adcch_conf, ADCCH_POS_BANDGAP, ADCCH_NEG_NONE, inputgain);
	//adcch_write_configuration(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH, &adcch_conf);
	//adc_enable(&ALPHASENSE_ADC);
	//adc_start_conversion(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH);
	//adc_wait_for_interrupt_flag(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH);
	//const uint16_t gain = adc_get_result(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH);
	//adc_disable(&ALPHASENSE_ADC);
	////sprintf_P(szBUF,PSTR("gain: %u\t"),gain);
	////debug_string(NORMAL,szBUF,false);
	
	
	adcch_set_input(&adcch_conf, ADCCH_POS_PIN0, ADCCH_NEG_NONE, inputgain);
	adcch_write_configuration(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH, &adcch_conf);
	adc_enable(&ALPHASENSE_ADC);
	adc_start_conversion(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH);
	adc_wait_for_interrupt_flag(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH);
	adc_start_conversion(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH);
	adc_wait_for_interrupt_flag(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH);
	const int16_t adc_w = adc_get_result(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH)-off;
	adc_disable(&ALPHASENSE_ADC);
	//sprintf_P(szBUF,PSTR("ADC_WORK: %u\t"),adc_w);
	//debug_string(NORMAL,szBUF,false);
	
	adcch_set_input(&adcch_conf, ADCCH_POS_PIN2, ADCCH_NEG_NONE, inputgain);
	adcch_write_configuration(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH, &adcch_conf);
	adc_enable(&ALPHASENSE_ADC);
	adc_start_conversion(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH);
	adc_wait_for_interrupt_flag(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH);
	adc_start_conversion(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH);
	adc_wait_for_interrupt_flag(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH);
	const int16_t adc_a = adc_get_result(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH)-off;
	adc_disable(&ALPHASENSE_ADC);
	//sprintf_P(szBUF,PSTR("ADC_AUX: %u\r\n"),adc_a);
	//debug_string(NORMAL,szBUF,false);	
	
	
	
	//adc_enable(&ALPHASENSE_ADC);
	//
	//for (int i=0;i<elements;i++)
	//{
		//adc_start_conversion(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH);
		//adc_wait_for_interrupt_flag(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH);
		//adc_start_conversion(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH);
		//adc_wait_for_interrupt_flag(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH);
		//result[i]=adc_get_result(&ALPHASENSE_ADC, ALPHASENSE_ADC_CH);
//
	//}
	
	//adc_disable(&ALPHASENSE_ADC);
	
	PORTB.PIN0CTRL = PORT_OPC_PULLUP_gc;
	PORTB.PIN2CTRL = PORT_OPC_PULLUP_gc;
	PORTB.PIN6CTRL = PORT_OPC_PULLUP_gc;
	
	g_recordingData_Alphasense = true;
	g_partialSumWork+=(int32_t)adc_w;
	g_partialSumAux+=(int32_t)adc_a;
	g_partialCount_Alphasense++;
	g_recordingData_Alphasense = false;
	
	//sprintf_P(szBUF,PSTR("Sample: %u\tPartialSumWork: %lu\tPartialSumAux: %lu\r\n"),g_partialCount, g_partialSumWork,g_partialSumAux);
	//debug_string(NORMAL,szBUF,false);
	
	//ps->working = adc_w;
	//ps->aux = adc_a;
}
示例#6
0
/**
 * \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);
}
void vControl ( void *pvParameters )
{
	portTickType xLastWakeTime;
	signed char valx, valy;
	unsigned char ls, rs, lb, rb;

	can_frame_t out_frame;
	can_frame_t in_frame;
	out_frame.id = 1;
	out_frame.dlc = 6;

	xLastWakeTime = xTaskGetTickCount ();

	/* Button init */
	buttons_init ();

	/* FSM init */
	fsm_init ();

	/* CAN init */
	can_init ();

	/* ADC init */
	adc_init ( ctrlNUM_ADC_VALUES );

	/* Touch init */
	touch_init ( 30, 30, 30, 30 );

	while (1)
	{
		vTaskDelayUntil ( &xLastWakeTime, ctrlTASK_FREQUENCY );

		if ( adc_conversion_complete () == pdTRUE )
		{
			adc_disable ();
			adc_get_value ( &valx, 0 );
			adc_get_value ( &valy, 0 );
			touch_measure ( &ls, &rs, &lb, &rb );

			out_frame.data[0] = valx;
			out_frame.data[1] = valy;
			out_frame.data[2] = ls;
			out_frame.data[3] = rs;
			out_frame.data[4] = lb;
			out_frame.data[5] = rb;

			if (fsm_get_state() == ST_PLAY)
			{
				can_transmit (&out_frame);
			}
						
			can_receive (&in_frame, 0);

			if (in_frame.data[0] == GAME_SENSOR_TRIGGERED)
			{
				// TODO: set triggered state
				fsm_event_t *event = pvPortMalloc (sizeof (fsm_event_t));
				event->type = EV_STOP;
				event->ptr = NULL;
				fsm_event_put (event, portMAX_DELAY);
				in_frame.data[0] = 0;
			}
			else if (in_frame.data[0] == GAME_SENSOR_CLEARED)
			{
				// TODO: set cleared state
				in_frame.data[0] = 0;
			}

			adc_enable ();
			adc_conversion_start ();
		}

		fsm_update ();
	}
}
示例#8
0
文件: ui.c 项目: AndreyMostovov/asf
void ui_wakeup(void)
{
	backlight_start_pwm();
	adc_enable(&LIGHT_SENSOR_ADC_MODULE);
	led_power_on();
}
示例#9
0
int main(void)
{
	system_init();
	clock_init();
	led_init();	led_set(0x01); //show life
	UART_Init(BAUD); UART_Write("\nInit"); //Show UART life
	motor_init();
	adc_init();
	
	
	//Enable Analog pins
	adc_enable(CHANNEL_SENSOR_LEFT); 
    adc_enable(CHANNEL_SENSOR_RIGHT);	
    adc_enable(CHANNEL_SENSOR_FRONT);

	
	//Sensor value variables
	uint16_t sensor_left_value = 0; uint16_t sensor_right_value  = 0; uint16_t sensor_front_value  = 0;

	//Analog inputSignal conditioning arrays
	circBuf_t left_buffer; circBuf_t right_buffer; 	circBuf_t front_buffer;

    //Initialise sensor averaging buffers
	initCircBuf(&left_buffer, ROLLING_AVERAGE_LENGTH);
	initCircBuf(&right_buffer, ROLLING_AVERAGE_LENGTH);
	initCircBuf(&front_buffer, ROLLING_AVERAGE_LENGTH);

		
	//UART output buffer
	char buffer[UART_BUFF_SIZE] = {0};

	//=====Application specific variables=====								//TODO: initialise circbuff
	circBuf_t sweep_times;
	initCircBuf(&sweep_times, SWEEP_TIME_MEMORY_LENGTH);
	short sweep_del_t_last = 0;
	short sweep_end_t_last = 0;
	
	//time when front sensor begins to see grey.
	uint32_t grey_time_start = 0;


	bool sweep_ended = FALSE;
	//set high if the front sensor crosses the line
	bool front_crossed_black = FALSE; 
	//set high if front finds finish line
	bool front_crossed_grey = FALSE;

	bool sensor_update_serviced = TRUE;
	
	action current_action = IDLE;
	
	int16_t forward_speed = DEFAULT_FORWARD_SPEED;
	int16_t turn_speed = DEFAULT_SPEED;
	
	//Scheduler variables
	uint32_t t = 0;	

	//Loop control time variables
	uint32_t maze_logic_t_last = 0;
	uint32_t sample_t_last = 0;
	uint32_t UART_t_last = 0;


	clock_set_ms(0);
	sei(); // Enable all interrupts
	UART_Write("ialized\n");

	//wait for start command
	DDRD &= ~BIT(7);
	PORTD |= BIT(7);
	
	
	//motor_set(128, 128);
	while((PIND & BIT(7)))
	{
		continue;
	}
	

	
	while(1)
	{
		                                                                                                                         
		t = clock_get_ms();
		
		//check if a sensor update has occured
		if ((sensor_update_serviced == FALSE) && 
			(t%MAZE_LOGIC_PERIOD == 0) && (t != maze_logic_t_last))
		{
			sensor_update_serviced = TRUE;


			// finishing condition is a grey read for a set period
			if(is_grey(sensor_front_value) && front_crossed_grey == FALSE)
			{
				front_crossed_grey = TRUE;
				grey_time_start = t;	                                   //TODO: adjust so that finishing condition is a 1/2 whole sweeps on grey line
			}
			else if (is_grey(sensor_front_value) && front_crossed_grey == TRUE)
			{
				//
				if ((grey_time_start + GREY_TIME) <= t )
				{
					// Finish line found. Stop robot.
					maze_completed(); // wait for button push
					front_crossed_grey = FALSE;
				}

			}
			else
			{
				front_crossed_grey = FALSE;
			}
			
			//see if the front sensor crosses the line in case we run into a gap
			if(is_black(sensor_front_value)&&front_crossed_black == FALSE)
			{
				front_crossed_black = TRUE;
				//check for false finish line
				if(front_crossed_grey)
					front_crossed_grey = FALSE; //false alarm
			}	
			
			// when both rear sensors go black, this indicates an intersection (turns included).
			// try turning left
			if(is_black(sensor_left_value) && is_black(sensor_right_value))
			{
				sweep_ended = TRUE;
				motor_set(0, 255);									
				PORTB |= BIT(3);
				PORTB |= BIT(4);
			}
			
			//when both sensors are completely white this indicates a dead end or a tape-gap
			else if (is_white(sensor_left_value) && is_white(sensor_right_value))
			{
				sweep_ended = TRUE;
				PORTB &= ~BIT(3);
				PORTB &= ~BIT(4);
				//current_action = ON_WHITE;
				//Check if the front sensor is on black, or has been during the last sweep.
				if(is_black(sensor_front_value) | front_crossed_black)
					motor_set(255, 255);
				else if (is_white(sensor_front_value))
					motor_set(-255, 255);
			}				
			
			//sweep to the side that reads the darkest value			
			else if (sensor_left_value + SENSOR_TOLLERANCE < sensor_right_value)
			{
				PORTB &= ~BIT(3);
				PORTB |= BIT(4);
				if (current_action == SWEEP_LEFT)
					sweep_ended = TRUE;
				current_action = SWEEP_RIGHT;
				motor_set(forward_speed + turn_speed, forward_speed);
			}
			else if(sensor_right_value + SENSOR_TOLLERANCE< sensor_left_value)
			{
				PORTB |= BIT(3);
				PORTB &= ~BIT(4);			
				if (current_action == SWEEP_RIGHT)
					sweep_ended = TRUE;
				current_action = SWEEP_LEFT;
				motor_set(forward_speed, forward_speed+ turn_speed);
			}

            //If a new sweep started this cycle, find how long it took
            if (sweep_ended)
            {
            	//reset front black crossing detection variable
				sweep_ended = FALSE;
				
				if (front_crossed_black)
					front_crossed_black = FALSE;

				//Calculate sweep time
				sweep_del_t_last = t - sweep_end_t_last;
				sweep_end_t_last = t;
				writeCircBuf(&sweep_times, sweep_del_t_last);
				
				//adjust turn_speed for battery level.
				if (sweep_del_t_last > IDEAL_SWEEP_TIME)
				{
					turn_speed += 5;
				}					
				if (sweep_del_t_last < IDEAL_SWEEP_TIME)
				{
					turn_speed -= 5;
				}					
					
				turn_speed = regulate_within(turn_speed, MIN_TURN_SPEED, MAX_TURN_SPEED);
				
			}
		}
		
		//Sensor value update
 		if((t%SAMPLE_PERIOD == 0) & (t!=sample_t_last))
		{
            sample_t_last = t;
            //read in analog values
            sensor_update(CHANNEL_SENSOR_LEFT, &left_buffer, &sensor_left_value );
            sensor_update(CHANNEL_SENSOR_RIGHT, &right_buffer, &sensor_right_value );
            sensor_update(CHANNEL_SENSOR_FRONT, &front_buffer, &sensor_front_value );
			sensor_update_serviced = FALSE;

		}
		
		//display debug information		
		if((t%UART_PERIOD == 0) & (t != UART_t_last) & UART_ENABLED)
		{
			UART_t_last = t;
			
			sprintf(buffer, "sweep_time: %u \n", sweep_del_t_last);
			UART_Write(buffer);

			sprintf(buffer, "L: %u F: %u R: %u", sensor_left_value, sensor_front_value, sensor_right_value);
			UART_Write(buffer);
			UART_Write("\n");
		}
	}
}
示例#10
0
int
main(void)
{
	uint8_t state = 0;

	serial_baud_9600();
	serial_mode_8e1();
	serial_transmitter_enable();

	sleep_mode_idle();

	pin13_mode_output();
	pin13_low();

	/* setup timer2 to trigger interrupt a
	 * once every millisecond
	 * 128 * (124 + 1) / 16MHz = 1ms */
	timer2_mode_ctc();
	timer2_clock_d128();
	timer2_compare_a_set(124);
	timer2_interrupt_a_enable();

	ow_timer_init();

	adc_reference_internal_5v();
	adc_pin_select(5);
	adc_clock_d128();
	adc_trigger_freerunning();
	adc_trigger_enable();
	adc_interrupt_enable();
	adc_enable();

	sei();
	start_temp_measure();

	while (1) {
		uint16_t value;

		cli();
		if (!new_value && !ev_timer) {
			sleep_enable();
			sei();
			sleep_cpu();
			sleep_disable();
			continue;
		}
		sei();

		if (new_value) {
			value = adc_data();
			new_value = 0;

			if (state && value < BOUND_LOW) {
				uint16_t now = time;
				char *p, *q;

				timer2_clock_reset();
				time = 0;

				pin13_low();

				p = sprint_uint16_b10(buf, now);
				*p++ = ' ';
				q= last_temp_buf;
				while (*q)
					*p++ = *q++;
				*p++ = '\n';
				*p = '\0';
				serial_puts(buf);

				state = 0;
				continue;
			}

			if (value > BOUND_HIGH) {
				pin13_high();
				state = 1;
			}
		}

		if (ev_timer)
			handle_timer();
	}
}
示例#11
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);
}