Exemplo n.º 1
0
/**
 ****************************************************************************************
 * @brief Gets ADC sample from VBAT1V or VBAT3V power supplies.
 *
 * @param[in] sample_vbat1v :true = sample VBAT1V, false = sample VBAT3V
 *
 * @return ADC VBAT1V or VBAT3V sample
 ****************************************************************************************
 */
uint32_t adc_get_vbat_sample(bool sample_vbat1v)
{
    uint32_t adc_sample;
    
    adc_init(GP_ADC_SE, GP_ADC_SIGN);

    if (sample_vbat1v)
        adc_enable_channel(ADC_CHANNEL_VBAT1V);
    else
        adc_enable_channel(ADC_CHANNEL_VBAT3V);

    adc_sample = adc_get_sample();

    adc_init(GP_ADC_SE, 0);

    if (sample_vbat1v)
        adc_enable_channel(ADC_CHANNEL_VBAT1V);
    else
        adc_enable_channel(ADC_CHANNEL_VBAT3V);

    adc_sample += adc_get_sample();

    adc_disable();

    return adc_sample;
}
Exemplo n.º 2
0
 /**************************************************************************
 Initializes the analog pins.
 **************************************************************************/
 int analogInit(void)
 {
	 pmc_enable_periph_clk(ID_ADC);
	 adc_init(ADC,sysclk_get_main_hz(),1000000,8);
	 adc_configure_timing(ADC,0,ADC_SETTLING_TIME_3,1);
	 adc_set_resolution(ADC,ADC_MR_LOWRES_BITS_12);
	 adc_enable_channel(ADC,ADC_CHANNEL_7);
	 adc_enable_channel(ADC,ADC_CHANNEL_6);
	 adc_enable_channel(ADC,ADC_CHANNEL_5);
	 adc_configure_trigger(ADC,ADC_TRIG_SW,0);
 }
Exemplo n.º 3
0
uint8_t battery_get_lvl(uint8_t batt_type)
{
	uint8_t batt_lvl;
	uint16_t adc_sample;
	volatile int i;

	adc_init(GP_ADC_SE, GP_ADC_SIGN);
	
#if JPLUS_BAT_TYPE
	adc_enable_channel(ADC_CHANNEL_P01);//ADC_CHANNEL_VBAT3V
#else	
	adc_enable_channel(ADC_CHANNEL_VBAT3V);//ADC_CHANNEL_P00
#endif
	
  adc_sample = adc_get_sample();

	adc_init(GP_ADC_SE, 0);
  
#if JPLUS_BAT_TYPE
	adc_enable_channel(ADC_CHANNEL_P01);//ADC_CHANNEL_VBAT3V
#else	
	adc_enable_channel(ADC_CHANNEL_VBAT3V);//ADC_CHANNEL_P00
#endif

	adc_sample += adc_get_sample();
	
	adc_disable();
	
    adc_sample >>= 4;
    adc_sample <<= 4;
    
    if(old_batt_level == 0)
        old_batt_level = 0xFF;
    
    if(batt_lvl > old_batt_level)
        batt_lvl = old_batt_level;
    
    switch (batt_type)
    {
        case BATT_CR2032:
            batt_lvl = batt_cal_cr2032(adc_sample);
            break;
				case BATT_JPLUS:		//gsx,custom.
            batt_lvl = batt_cal_jplus(adc_sample);
            break;
        default:
            batt_lvl = 0;
    }   
    
	return batt_lvl;
}
Exemplo n.º 4
0
/**
 * \brief Initialize ADC.
 */
static void demo_config_adc( void )
{
	/* Enable peripheral clock. */
	pmc_enable_periph_clk(ID_ADC);
	/* Initialize ADC. */
	/*
	 * Formula: ADCClock = MCK / ( (PRESCAL+1) * 2 )
	 * For example, MCK = 64MHZ, PRESCAL = 4, then:
	 * ADCClock = 64 / ((4+1) * 2) = 6.4MHz;
	 */
	/* Formula:
	 *     Startup  Time = startup value / ADCClock
	 *     Startup time = 64 / 6.4MHz = 10 us
	 */
	adc_init(ADC, sysclk_get_cpu_hz(), 6400000, ADC_STARTUP_TIME_4);
	/* Formula:
	 *     Transfer Time = (TRANSFER * 2 + 3) / ADCClock
	 *     Tracking Time = (TRACKTIM + 1) / ADCClock
	 *     Settling Time = settling value / ADCClock
	 *
	 *     Transfer Time = (1 * 2 + 3) / 6.4MHz = 781 ns
	 *     Tracking Time = (1 + 1) / 6.4MHz = 312 ns
	 *     Settling Time = 3 / 6.4MHz = 469 ns
	 */
	adc_configure_timing(ADC, TRACKING_TIME, ADC_SETTLING_TIME_3, TRANSFER_PERIOD);
	adc_check(ADC, sysclk_get_cpu_hz());

	/* Hardware trigger TIOA0. */
	adc_configure_trigger(ADC, ADC_TRIG_TIO_CH_1, 0);
	/* Enable channels for x,y and z. */
	adc_enable_channel(ADC, ADC_CHANNEL_POTENTIOMETER);

	/* Configure TC. */
	demo_configure_tc0();
}
Exemplo n.º 5
0
uint8_t batt_read_lvl(void)
{
		uint8_t batt_lvl;
		uint16_t adc_sample;
		volatile int i;

	adc_init();
	
//	for (i = 0; i<=1000; i++); //delay
	
	adc_enable_channel(0x07);
	
	adc_sample = adc_get_sample();
	
	adc_disable();
			  
	//calculate remaining battery life 
	if (adc_sample > 0x308)
		batt_lvl = 100;
	else if (adc_sample <= 0x308 && adc_sample > 0x2D6) 
		batt_lvl = 28 + (uint8_t)(((float)((float)(adc_sample - 0x2D6)/(float)(0x308 - 0x2D6))) * 72) ;
	else if (adc_sample <= 0x2D6 && adc_sample > 0x26C) 
		batt_lvl = 4 + (uint8_t)(((float)((float)(adc_sample - 0x26C)/(float)(0x2D6 - 0x26C))) * 24) ;
	else if (adc_sample <= 0x26C && adc_sample > 0x205) 
		batt_lvl = (uint8_t)(((float)((float)(adc_sample - 0x205)/(float)(0x26C - 0x205))) * 4) ;
	else 
		batt_lvl = 0;
		
	return batt_lvl;	
}
Exemplo n.º 6
0
int adc_read_channel(enum adc_channel ch)
{
	/* voltage 0 ~ 3v = adc data register raw data 0 ~ 3FFh (10-bit ) */
	uint16_t adc_raw_data;
	int num;
	int adc_ch;

	adc_ch = adc_channels[ch].channel;

	adc_enable_channel(adc_ch);

	/* Maximum time for waiting ADC conversion is ~1.525ms */
	for (num = 0x00; num < 100; num++) {
		/* delay ~15.25us */
		IT83XX_GCTRL_WNCKR = 0;

		/* data valid of adc channel[x] */
		if (IT83XX_ADC_ADCDVSTS & (1 << adc_ch)) {
			/* read adc raw data msb and lsb */
			adc_raw_data = (*adc_ctrl_regs[adc_ch].adc_datm << 8) +
				*adc_ctrl_regs[adc_ch].adc_datl;

			/* W/C data valid flag */
			IT83XX_ADC_ADCDVSTS = (1 << adc_ch);

			adc_disable_channel(adc_ch);
			return adc_raw_data * adc_channels[ch].factor_mul /
				adc_channels[ch].factor_div +
				adc_channels[ch].shift;
		}
	}

	adc_disable_channel(adc_ch);
	return ADC_READ_ERROR;
}
Exemplo n.º 7
0
/**
 * \brief Initialize ADC.
 */
static void demo_config_adc( void )
{
	/* Enable peripheral clock. */
	pmc_enable_periph_clk(ID_ADC);
	/* Initialize ADC. */

	/* startup = 10:    640 periods of ADCClock
	 * for prescale = 4
	 *     prescale: ADCClock = MCK / ( (PRESCAL+1) * 2 ) => 64MHz /
	 * ((4+1)*2) = 6.4MHz
	 *     ADC clock = 6.4 MHz
	 */
	adc_init(ADC, sysclk_get_cpu_hz(), 6400000, 10);

	adc_configure_timing(ADC, 0, ADC_SETTLING_TIME_3, 1);
	adc_check(ADC, sysclk_get_cpu_hz());

	/* Hardware trigger TIOA0. */
	adc_configure_trigger(ADC, ADC_TRIG_TIO_CH_1, 0);
	/* Enable channels for x,y and z. */
	adc_enable_channel(ADC, ADC_CHANNEL_POTENTIOMETER);

	/* Configure TC. */
	demo_configure_tc0();
}
Exemplo n.º 8
0
/* Enables analog to digital conversion */
void adc_config(void)
{
	pmc_enable_periph_clk(ID_ADC);
	adc_init(ADC, sysclk_get_main_hz(), 20000000, 0);
	adc_configure_timing(ADC, 0, 0, 0);
	adc_set_resolution(ADC, ADC_MR_LOWRES);
	adc_enable_channel(ADC, ADC_CHANNEL_10);
	adc_configure_trigger(ADC, ADC_TRIG_SW, 0);
}
Exemplo n.º 9
0
/**
 * \brief adc_temp_sensor Application entry point.
 *
 * Initialize adc to 12-bit, enable channel 15,turn on
 * temp sensor, pdc channel interrupt for temp sensor
 * and start conversion.
 *
 * \return Unused (ANSI-C compatibility).
 */
int main(void)
{
	/* Initialize the SAM system. */
	sysclk_init();
	board_init();

	/* Disable watchdog. */
	WDT->WDT_MR = WDT_MR_WDDIS;

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

	/* 10 ms timer */
	if (SysTick_Config(sysclk_get_cpu_hz() / 100)) {
		puts("-F- Systick configuration error\r");
		while (1) {
		}
	}
	/* Enable peripheral clock. */
	pmc_enable_periph_clk(ID_ADC);
	/* Initialize ADC. */
	/*  startup = 8:    512 periods of ADCClock
	 * for prescale = 4
	 *     prescale: ADCClock = MCK / ( (PRESCAL+1) * 2 ) => 64MHz / ((4+1)*2) = 6.4MHz
	 *     ADC clock = 6.4 MHz
	 */
	adc_init(ADC, sysclk_get_cpu_hz(), 6400000, 8);

	adc_configure_timing(ADC, 0, ADC_SETTLING_TIME_3, 1);

	adc_configure_trigger(ADC, ADC_TRIG_SW, 0);

	adc_check(ADC, sysclk_get_cpu_hz());

	/* Enable channel for potentiometer. */
	adc_enable_channel(ADC, ADC_TEMPERATURE_SENSOR);

	/* Enable the temperature sensor. */
	adc_enable_ts(ADC);

	/* Enable ADC interrupt. */
	NVIC_EnableIRQ(ADC_IRQn);
	
	/* Start conversion. */
	adc_start(ADC);

	adc_read_buffer(ADC, gs_s_adc_values, BUFFER_SIZE);
	
	/* Enable PDC channel interrupt. */
	adc_enable_interrupt(ADC, ADC_ISR_RXBUFF);

	while (1) {
	}
}
Exemplo n.º 10
0
/*
 * Checking that an ADC channel is enabled.
 */
void test_adc_channel_enabled(void) {
	uint8_t channel = ADC_CHANNEL_0;

	// Check if that channel is disabled
	TEST_ASSERT_FALSE(ADC->ADC_CHSR & (0x1u << channel));

	adc_enable_channel(channel);

	// Check if that channel is enabled
	TEST_ASSERT_TRUE(ADC->ADC_CHSR & (0x1u << channel));
}
Exemplo n.º 11
0
/**
 * \brief Configure the ADC for the light sensor.
 */
static void configure_adc(void)
{
	/* Configure ADC pin for light sensor. */
	gpio_configure_pin(LIGHT_SENSOR_GPIO, LIGHT_SENSOR_FLAGS);

	/* Enable ADC clock. */
	pmc_enable_periph_clk(ID_ADC);

	/* Configure ADC. */
	adc_init(ADC, sysclk_get_cpu_hz(), 1000000, ADC_MR_STARTUP_SUT0);
	adc_enable_channel(ADC, ADC_CHANNEL_4);
	adc_configure_trigger(ADC, ADC_TRIG_SW, 1);
}
Exemplo n.º 12
0
void configure_ADC(void){
	
	/* Enable peripheral clock. */
	pmc_enable_periph_clk(ID_ADC);
	
	/* Initialize ADC. */
	/*
	 * Formula: ADCClock = MCK / ( (PRESCAL+1) * 2 )
	 * For example, MCK = 64MHZ, PRESCAL = 4, then:
	 * ADCClock = 64 / ((4+1) * 2) = 6.4MHz;
	 */
	/* Formula:
	 *     Startup  Time = startup value / ADCClock
	 *     Startup time = 64 / 6.4MHz = 10 us
	 */
	adc_init(ADC, sysclk_get_cpu_hz(), 6400000, STARTUP_TIME);
	
	/* Formula:
	 *     Transfer Time = (TRANSFER * 2 + 3) / ADCClock
	 *     Tracking Time = (TRACKTIM + 1) / ADCClock
	 *     Settling Time = settling value / ADCClock
	 *
	 *     Transfer Time = (1 * 2 + 3) / 6.4MHz = 781 ns
	 *     Tracking Time = (1 + 1) / 6.4MHz = 312 ns
	 *     Settling Time = 3 / 6.4MHz = 469 ns
	 */
	adc_configure_timing(ADC, TRACKING_TIME	, ADC_SETTLING_TIME_3, TRANSFER_PERIOD);

	/*
	* Configura trigger por software
	*/ 
	adc_configure_trigger(ADC, ADC_TRIG_SW, 0);

	/*
	* Checa se configuração 
	*/
	//adc_check(ADC, sysclk_get_cpu_hz());

	/* Enable channel for potentiometer. */
	adc_enable_channel(ADC, ADC_POT_CHANNEL);

	/* Enable ADC interrupt. */
	NVIC_EnableIRQ(ADC_IRQn);

	/* Start conversion. */
	adc_start(ADC);

	/* Enable PDC channel interrupt. */
	adc_enable_interrupt(ADC, ADC_ISR_RXBUFF);
}
Exemplo n.º 13
0
/*
 * Test getting the state of a channel (enabled or not).
 * Requires "test_adc_channel_enabled" and
 * "test_adc_channel_disabled" to pass it's tests
 */
void test_adc_channel_status(void) {
	uint32_t channel = ADC_CHANNEL_0;
	adc_enable_channel(channel);

	// Check if registry value and function has the same value
	TEST_ASSERT_TRUE(ADC->ADC_CHSR & (0x1u << channel));
	TEST_ASSERT_TRUE(adc_channel_enabled(channel));

	adc_disable_channel(channel);

	// Check if registry value and function has the same value
	TEST_ASSERT_FALSE(ADC->ADC_CHSR & (0x1u << channel));
	TEST_ASSERT_FALSE(adc_channel_enabled(channel));
}
Exemplo n.º 14
0
void configure_adc(void)
{
	/* Enable peripheral clock. */
	pmc_enable_periph_clk(ID_ADC);
	adc_init(ADC, sysclk_get_cpu_hz(), 6400000, STARTUP_TIME);
	adc_configure_timing(ADC, TRACKING_TIME	, ADC_SETTLING_TIME_3, TRANSFER_PERIOD);
	adc_configure_trigger(ADC, ADC_TRIG_SW, 0);
	/* Enable chnnel for potentiometer. */
	adc_enable_channel(ADC, ADC_POT_CHANNEL);
	/* Enable ADC interrupt. */
	NVIC_EnableIRQ(ADC_IRQn);
	/* Start conversion. */
	adc_start(ADC);
	adc_enable_interrupt(ADC, ADC_ISR_EOC5);
/**
 ****************************************************************************************
 * @brief Handles APP_SAMPLING_TIMER's expiration message. Samples ADC and writes value to characteristic.
 *
 * @param[in] msgid     Id of the message received.
 * @param[in] param     Pointer to the parameters of the message.
 * @param[in] dest_id   ID of the receiving task instance (TASK_GAP).
 * @param[in] src_id    ID of the sending task instance.
 *
 * @return If the message was consumed or not.
 ****************************************************************************************
 */
int app_adc_sampling_timer_handler(ke_msg_id_t const msgid,
                                      void *param,
                                      ke_task_id_t const dest_id,
                                      ke_task_id_t const src_id)
{
    
    adc_init(GP_ADC_SE, ADC_POLARITY_UNSIGNED); // Single ended mode
	adc_enable_channel(ADC_CHANNEL_P01);  // 
    
    app_adc_notify_upd_char(SWAP(adc_get_sample()));
    
    app_timer_set(APP_ADC_SAMPLING_TIMER, TASK_APP, APP_ADC_SAMPLING_TIMEOUT); //5 sec
    
    return (KE_MSG_CONSUMED);
    
}
Exemplo n.º 16
0
// Enable or disable a channel. Use AnalogCheckReady to make sure the ADC is ready before calling this.
void AnalogInEnableChannel(AnalogChannelNumber channel, bool enable)
{
	if ((unsigned int)channel < numChannels)
	{
		if (enable)
		{
			activeChannels |= (1u << channel);
#if SAM3XA || SAM4S
			adc_enable_channel(ADC, GetAdcChannel(channel));
#if SAM4S
			adc_set_calibmode(ADC);										// auto calibrate at start of next sequence
#endif
			if (GetAdcChannel(channel) == ADC_TEMPERATURE_SENSOR)
			{
				adc_enable_ts(ADC);
			}
#elif SAM4E || SAME70
			afec_ch_config cfg;
			afec_ch_get_config_defaults(&cfg);
			afec_ch_set_config(GetAfec(channel), GetAfecChannel(channel), &cfg);
			afec_channel_set_analog_offset(GetAfec(channel), GetAfecChannel(channel), 2048);	// need this to get the full ADC range
			afec_channel_enable(GetAfec(channel), GetAfecChannel(channel));
#if SAM4E
			afec_start_calibration(GetAfec(channel));					// do automatic calibration
#endif
#endif
		}
		else
		{
			activeChannels &= ~(1u << channel);
#if SAM3XA || SAM4S
			adc_disable_channel(ADC, GetAdcChannel(channel));
			if (GetAdcChannel(channel) == ADC_TEMPERATURE_SENSOR)
			{
				adc_disable_ts(ADC);
			}
#elif SAM4E || SAME70
			afec_channel_disable(GetAfec(channel), GetAfecChannel(channel));
#endif
		}
	}
}
Exemplo n.º 17
0
void app_adc_notify_enable(void)
{
		
    // Allocate the message
    struct adc_notify_enable_req* req = KE_MSG_ALLOC(ADC_NOTIFY_ENABLE_REQ, TASK_ADC_NOTIFY, TASK_APP,
                                                 adc_notify_enable_req);
  	
    req->conhdl = app_env.conhdl;
	req->sec_lvl = PERM(SVC, ENABLE);
    
	adc_init(GP_ADC_SE, ADC_POLARITY_UNSIGNED); // Single ended mode
	adc_enable_channel(ADC_CHANNEL_P01);  //
    
    req->adc_notify_val = SWAP(adc_get_sample());//dummy value
    req->feature = 0x00; //client CFG notif/ind disable
    
    // Send the message
    ke_msg_send(req);

}
Exemplo n.º 18
0
/**
 * \brief Initialize SAM3N_EK board for low power test.
 */
void init_specific_board(void)
{
    /* Configure all PIOs as inputs to save power */
    pio_set_input(PIOA, 0xFFFFFFFF, PIO_PULLUP);
    pio_set_input(PIOB, 0xFFFFFFFF, PIO_PULLUP);
    pio_set_input(PIOC, 0xFFFFFFFF, PIO_PULLUP);

    /* Disable USB Clock */
    pmc_disable_upll_clock();

    /* Disable PIO pull-up for PA0 (VBUS_USB) */
    pio_pull_up(PIOA, (0x1 << 0), 0);

    /* Initialize ADC pin as ADC input mode to save power */
    adc_enable_channel(ADC, ADC_CHANNEL_0);
    adc12b_enable_channel(ADC12B, ADC_CHANNEL_3);

    /* Enable the PMC clocks of push button for wakeup */
    pmc_enable_periph_clk(ID_PIOA);
    pio_handler_set_priority(PIOA, PIOA_IRQn, IRQ_PRIOR_PIO);
}
int app_adc_notify_cfg_ind_handler(ke_msg_id_t const msgid,
                                      struct adc_notify_cfg_ind const *param,
                                      ke_task_id_t const dest_id,
                                      ke_task_id_t const src_id)
{	
    
    if (param->val == PRF_CLI_START_NTF)
    {
        adc_init(GP_ADC_SE, 0); // Single ended mode
        adc_enable_channel(ADC_CHANNEL_P01);  //
    
        app_adc_notify_upd_char(SWAP(adc_get_sample()));
    
        app_timer_set(APP_ADC_SAMPLING_TIMER, TASK_APP, APP_ADC_SAMPLING_TIMEOUT); //5 sec
    }
    else if (param->val == PRF_CLI_STOP_NTFIND)
    {
        ke_timer_clear(APP_ADC_SAMPLING_TIMER, TASK_APP); //5 sec
    }
    
    return (KE_MSG_CONSUMED);
}
/**
 * \brief Initialize SAM3N_EK board for low power test.
 */
void init_specific_board(void)
{
	/* Configure all PIOs as inputs to save power */
	pio_set_input(PIOA, 0xFFFFFFFF, PIO_PULLUP);
	pio_set_input(PIOB, 0xFFFFFFFF, PIO_PULLUP);
	pio_set_input(PIOC, 0xFFFFFFFF, PIO_PULLUP);

	/* Disable USB Clock */
	pmc_disable_udpck();

	/* Disable PIO pull-up for PB10(USB_DDM), PB11(USB_DDP) */
	pio_pull_up(PIOB, (0x3 << 10), 0);
	/* Disable PIO pull-up for PC21(USB_CNX) */
	pio_pull_up(PIOC, (0x1 << 21), 0);

	/* Initialize ADC pin as ADC input mode to save power */
	adc_enable_channel(ADC, ADC_CHANNEL_4);

	/* Enable the PMC clocks of push button for wakeup */
	pmc_enable_periph_clk(ID_PIOB);
	pio_handler_set_priority(PIOB, PIOB_IRQn, IRQ_PRIOR_PIO);
}
Exemplo n.º 21
0
uint16_t hal_analog_read(uint8_t adc_channel)
{
    uint32_t ulValue = 0;

    // Enable the corresponding channel
    adc_enable_channel( ADC, adc_channel );

    // Start the ADC
    adc_start( ADC );

    // Wait for end of conversion
    while ((adc_get_status(ADC) & ADC_ISR_DRDY) != ADC_ISR_DRDY)
      ;

    // Read the value
    ulValue = adc_get_latest_value(ADC);
    //!! ulValue = mapResolution(ulValue, ADC_RESOLUTION, _readResolution);

    // Disable the corresponding channel
    adc_disable_channel(ADC, adc_channel);

    return ulValue;
}
/**
 * \brief Initialize SAM3N_EK board for low power test.
 */
void init_specific_board(void)
{
	/* Configure all PIOs as inputs to save power */
	pio_set_input(PIOA, 0xFFFFFFFF, PIO_PULLUP);
	pio_set_input(PIOB, 0x0FFFFFFF, PIO_PULLUP); /* Exclude JTAG pins */
	pio_set_input(PIOC, 0xFFFFFFFF, PIO_PULLUP);
	pio_set_input(PIOD, 0x7FFFFFFF, PIO_PULLUP);
	pio_set_input(PIOE, 0xFFFFFFFF, PIO_PULLUP);
	pio_set_input(PIOF, 0x3F, PIO_PULLUP);

	/* Disable USB Clock */
	pmc_disable_udpck();
	pmc_disable_upll_clock();

	/* Disable PIO pull-up for PB4, PB5, PB6, PB7 */
	pio_pull_up(PIOB, (0xF << 4), 0);

	/* Initialize ADC pin as ADC input mode to save power */
	adc_enable_channel(ADC, ADC_CHANNEL_1);

	/* Enable the PMC clocks of push button for wakeup */
	pmc_enable_periph_clk(ID_PIOB);
	pio_handler_set_priority(PIOB, PIOB_IRQn, IRQ_PRIOR_PIO);
}
Exemplo n.º 23
0
int analogInit(int pinNumber)
{
	/* 
	 * The pin number is the analog input pin on the DUe board, see http://www.arduino.cc/en/Hacking/PinMappingSAM3X
	 * Obviously it starts at analog 0 which is equivalent to the analog input on PA16
	 * so you need to figure out which AD channel this corresponds to
	 *
	 * See code example http://asf.atmel.com/docs/latest/sam.drivers.adc.adc_example.arduino_due_x/html/sam_adc_quickstart.html
	 * It is assumed that the AD-converter is using 12 bits
	 */
	
	
	pmc_enable_periph_clk(ID_ADC);	/* power the clock for the ADC with pmc_enable_periph_clk(ID_ADC) */
	adc_init(ADC,sysclk_get_main_hz(),1000000,8); 		
	adc_configure_timing(ADC,0,ADC_SETTLING_TIME_3,1);
	adc_set_resolution(ADC,ADC_MR_LOWRES_BITS_12);	
		
	adc_enable_channel(ADC,ADC_CHANNEL_7);
	//adc_enable_channel(ADC,ADC_CHANNEL_6);
	adc_configure_trigger(ADC,ADC_TRIG_SW,0);				
	
	
	return 0;	/* if everything is ok */
}
Exemplo n.º 24
0
/**
 * \brief (Re)Sart ADC sample.
 * Initialize ADC, set clock and timing, set ADC to given mode.
 */
static void _configure_adc(void)
{
	uint8_t i = 0;

	/* Check if sequence mode is necessary */
	_test_mode.sequence_enabled = 0;
	for(i = 0; i < NUM_CHANNELS; i++) {
		if(i != adc_channel_used[i]) {
			_test_mode.sequence_enabled = 1;
			break;
		}
	}

	/* Update channel number */
	for (i = 0; i < NUM_CHANNELS; i++) {
		_data.channel[i] = adc_channel_used[i];
	}

	/* Enable/disable sequencer */
	if (_test_mode.sequence_enabled) {

		/* Set user defined channel sequence */
		adc_set_sequence_by_list(adc_channel_used, NUM_CHANNELS);
		/* Enable sequencer */
		adc_set_sequence_mode(true);

	} else {
		/* Disable sequencer */
		adc_set_sequence_mode(false);
	}

	/* Enable channels, gain, single mode */
	for (i = 0; i < NUM_CHANNELS; i++) {
		adc_enable_channel(_data.channel[i]);
	}

	/* Set power save */
	if (_test_mode.power_save_enabled) {
		adc_set_sleep_mode(true);
	} else {
		adc_set_sleep_mode(false);
	}

	/* Transfer with/without DMA */
	/* Initialize XDMA driver instance with polling mode */

	/* Enable Data ready interrupt */
	uint32_t ier_mask = 0;
	for (i = 0; i < NUM_CHANNELS; i++) {
		ier_mask |= 0x1u << _data.channel[i];
	}
	adc_enable_it(ier_mask) ;

	/* Set ADC irq handler */
	aic_set_source_vector(ID_ADC, adc_irq_handler);

	/* Configure trigger mode and start convention */
	switch (_test_mode.trigger_mode) {
		case TRIGGER_MODE_SOFTWARE:
			/* Disable hardware trigger */
			adc_set_trigger(0);
			/* No trigger, only software trigger can start conversions */
			adc_set_trigger_mode(ADC_TRGR_TRGMOD_NO_TRIGGER);
			aic_enable(ID_ADC);
			break;
		case TRIGGER_MODE_ADTRG:
			pio_configure(pin_adtrg, ARRAY_SIZE(pin_adtrg));
			break;
		case TRIGGER_MODE_TIMER :
			/* Enable hardware trigger */
			adc_set_trigger(ADC_MR_TRGSEL_ADC_TRIG1);
			/* Trigger timer*/
			adc_set_trigger_mode(ADC_TRGR_TRGMOD_PERIOD_TRIG);
			adc_set_trigger_period(250);
			aic_enable(ID_TC0);
			break;
		default :
			break;
	}
}
Exemplo n.º 25
0
/**
 * \brief Example entry point.
 *
 * Initialize ADC to 12-bit, enable channel "ADC_CHANNEL_POTENTIOMETER", then
 * enable hardware trigger with TIOA0 every second. Finally, start conversion.
 *
 * \return Unused (ANSI-C compatibility).
 */
int main(void)
{
	uint8_t c_choice;
	int16_t s_adc_value;
	int16_t s_threshold = 0;

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


	configure_console();

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

	/* Initialize threshold. */
	gs_us_low_threshold = 0x0;
	gs_us_high_threshold = MAX_DIGITAL;

	/* Enable peripheral clock. */
	pmc_enable_periph_clk(ID_ADC);
	/* Initialize ADC. */
	/* startup = 10:    640 periods of ADCClock
	 * for prescale = 4
	 *     prescale: ADCClock = MCK / ( (PRESCAL+1) * 2 ) => 64MHz / ((4+1)*2) = 6.4MHz
	 *     ADC clock = 6.4 MHz
	 */
	adc_init(ADC, sysclk_get_cpu_hz(), 6400000, 10);
#if SAM3S ||  SAM3XA || SAM4S
	adc_configure_timing(ADC, 0, ADC_SETTLING_TIME_3, 1);
#elif SAM3N
	adc_configure_timing(ADC, 0);
#endif
	adc_check(ADC, sysclk_get_cpu_hz());

	/* Hardware trigger TIOA0. */
	adc_configure_trigger(ADC, ADC_TRIG_TIO_CH_0, 0);
	/* Enable channels for x,y and z. */
	adc_enable_channel(ADC, ADC_CHANNEL_POTENTIOMETER);

	/* Configure TC. */
	configure_tc0();

	/* Channel 5 has to be compared. */
	adc_set_comparison_channel(ADC, ADC_CHANNEL_POTENTIOMETER);
	/* Compare mode, in the window. */
	adc_set_comparison_mode(ADC, ADC_EMR_CMPMODE_IN);

	/* Set up Threshold. */
	adc_set_comparison_window(ADC, gs_us_high_threshold, gs_us_low_threshold);

	/* Enable ADC interrupt. */
	NVIC_EnableIRQ(ADC_IRQn);

	/* Start TC0 and hardware trigger. */
	tc_start(TC0, 0);

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

	while (1) {
		while (uart_read(CONSOLE_UART, &c_choice)) {
		}
		printf("%c\r\n", c_choice);

		switch (c_choice) {
		case '0':
			s_adc_value = adc_get_channel_value(ADC,
					ADC_CHANNEL_POTENTIOMETER);
			printf("-I- Current voltage is %d mv, %d%% of ADVREF\n\r",
			(s_adc_value * VOLT_REF / MAX_DIGITAL), (s_adc_value * 100 / MAX_DIGITAL));
			break;

		case '1':
			puts("Low threshold is set to(mv):");
			s_threshold = get_voltage();
			puts("\r");

			if (s_threshold >= 0) {
				s_adc_value = s_threshold * MAX_DIGITAL /
						VOLT_REF;
				adc_set_comparison_window(ADC, 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);
			}
			break;

		case '2':
			puts("High threshold is set to(mv):");
			s_threshold = get_voltage();
			puts("\r");

			if (s_threshold >= 0) {
				s_adc_value = s_threshold * MAX_DIGITAL /
						VOLT_REF;
				adc_set_comparison_window(ADC, 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);
			}
			break;
		case '3':
			puts("-a. Below low threshold.\n\r"
					"-b. Above 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_comparison_mode();
			adc_set_comparison_mode(ADC, c_choice);
			printf("Comparison mode is %c.\n\r", 'a' + c_choice);
			break;

		case 'm':
		case 'M':
			display_menu();
			break;

		case 'i':
		case 'I':
			display_info();
			break;

		case 's':
		case 'S':
			enter_asleep();
			break;
		}
		puts("Press \'m\' or \'M\' to display the main menu again!\r");
	}
}
Exemplo n.º 26
0
/**
 * \brief Configure to trigger ADC by PWM Event Line.
 */
static void configure_pwm_trigger(void)
{
	/* PWM frequency in Hz. */
#define PWM_FREQUENCY               2
	/* Maximum duty cycle value. */
#define MAX_DUTY_CYCLE              1000

	/* Enable PWMC peripheral clock. */
	pmc_enable_periph_clk(ID_PWM);

	/* Disable PWM channel 0. */
	pwm_channel_disable(PWM, PWM_CHANNEL_0);

	gpio_configure_pin(PIN_PWMC_PWMH0_TRIG, PIN_PWMC_PWMH0_TRIG_FLAG);

	/* Set clock A to run at PWM_FREQUENCY * MAX_DUTY_CYCLE (clock B is not used). */
	pwm_clock_t pwm_clock_setting = {
		.ul_clka = PWM_FREQUENCY * MAX_DUTY_CYCLE,
		.ul_clkb = 0,
		.ul_mck = sysclk_get_cpu_hz()
	};
	pwm_init(PWM, &pwm_clock_setting);

	/* Configure PWMC for channel 0 (left-aligned). */
		pwm_channel_t pwm_trigger_channel = {
			.channel = PWM_CHANNEL_0,
			.alignment = PWM_ALIGN_LEFT,
			.polarity = PWM_LOW,
		.ul_prescaler = PWM_CMR_CPRE_CLKA,
		.ul_period = MAX_DUTY_CYCLE,
		.ul_duty = MAX_DUTY_CYCLE / 2
	};
	pwm_channel_init(PWM, &pwm_trigger_channel);

	pwm_cmp_t pwm_comparison_setting = {
		.unit = PWM_CMP_UNIT_0,
		.b_enable = true,
		.ul_value = MAX_DUTY_CYCLE / 2,
		.b_pulse_on_line_0 = true
	};
	pwm_cmp_init(PWM, &pwm_comparison_setting);


	/* Enable PWM channel 0. */
	pwm_channel_enable(PWM, PWM_CHANNEL_0);
	/* Set PWM Event Line 0 trigger. */
#if SAM3S || SAM3XA || SAM4S
	adc_configure_trigger(ADC, ADC_TRIG_PWM_EVENT_LINE_0, 0);
#elif SAM3U
#ifdef ADC_12B
	adc12b_configure_trigger(ADC12B, ADC12B_TRIG_PWM_EVENT_LINE_0);
#else
	adc_configure_trigger(ADC, ADC_TRIG_PWM_EVENT_LINE_0);
#endif
#endif
}
#endif

/**
 * \brief Read converted data through PDC channel.
 *
 * \param p_adc The pointer of adc peripheral.
 * \param p_s_buffer The destination buffer.
 * \param ul_size The size of the buffer.
 */
#if SAM3S || SAM3N || SAM3XA || SAM4S || SAM4C
static uint32_t adc_read_buffer(Adc * p_adc, uint16_t * p_s_buffer, uint32_t ul_size)
{
	/* Check if the first PDC bank is free. */
	if ((p_adc->ADC_RCR == 0) && (p_adc->ADC_RNCR == 0)) {
		p_adc->ADC_RPR = (uint32_t) p_s_buffer;
		p_adc->ADC_RCR = ul_size;
		p_adc->ADC_PTCR = ADC_PTCR_RXTEN;

		return 1;
	} else { /* Check if the second PDC bank is free. */
		if (p_adc->ADC_RNCR == 0) {
			p_adc->ADC_RNPR = (uint32_t) p_s_buffer;
			p_adc->ADC_RNCR = ul_size;

			return 1;
		} else {
			return 0;
		}
	}
}
#elif SAM3U
#ifdef ADC_12B
static uint32_t adc12_read_buffer(Adc12b * p_adc, uint16_t * p_s_buffer,
		uint32_t ul_size)
{
	/* Check if the first PDC bank is free. */
	if ((p_adc->ADC12B_RCR == 0) && (p_adc->ADC12B_RNCR == 0)) {
		p_adc->ADC12B_RPR = (uint32_t) p_s_buffer;
		p_adc->ADC12B_RCR = ul_size;
		p_adc->ADC12B_PTCR = ADC12B_PTCR_RXTEN;

		return 1;
	} else {	/* Check if the second PDC bank is free. */
		if (p_adc->ADC12B_RNCR == 0) {
			p_adc->ADC12B_RNPR = (uint32_t) p_s_buffer;
			p_adc->ADC12B_RNCR = ul_size;

			return 1;
		} else {
			return 0;
		}
	}
}
#else
static uint32_t adc_read_buffer(Adc * p_adc, uint16_t * p_s_buffer, uint32_t ul_size)
{
	/* Check if the first PDC bank is free. */
	if ((p_adc->ADC_RCR == 0) && (p_adc->ADC_RNCR == 0)) {
		p_adc->ADC_RPR = (uint32_t) p_s_buffer;
		p_adc->ADC_RCR = ul_size;
		p_adc->ADC_PTCR = ADC_PTCR_RXTEN;

		return 1;
	} else {	/* Check if the second PDC bank is free. */
		if (p_adc->ADC_RNCR == 0) {
			p_adc->ADC_RNPR = (uint32_t) p_s_buffer;
			p_adc->ADC_RNCR = ul_size;

			return 1;
		} else {
			return 0;
		}
	}
}
#endif
#endif

/**
 * \brief Start ADC sample.
 * Initialize ADC, set clock and timing, and set ADC to given mode.
 */
static void start_adc(void)
{
	/* Enable peripheral clock. */
#if SAM3S || SAM3N || SAM3XA || SAM4S || SAM4C
	uint32_t i;
	pmc_enable_periph_clk(ID_ADC);
#elif SAM3U
#ifdef ADC_12B
	pmc_enable_periph_clk(ID_ADC12B);
#else
	pmc_enable_periph_clk(ID_ADC);
#endif
#endif

	/* Initialize ADC. */
	/*
	 * Formula: ADCClock = MCK / ( (PRESCAL+1) * 2 )
	 * For example, MCK = 64MHZ, PRESCAL = 4, then:
	 * ADCClock = 64 / ((4+1) * 2) = 6.4MHz;
	 */
#if SAM3S || SAM3N || SAM3XA || SAM4S || SAM4C
	/* Formula:
	 *     Startup  Time = startup value / ADCClock
	 *     Startup time = 64 / 6.4MHz = 10 us
	 */
	adc_init(ADC, sysclk_get_cpu_hz(), 6400000, ADC_STARTUP_TIME_4);
#elif SAM3U
#ifdef ADC_12B
	/* Formula:
	 *     Startup  Time = (startup value + 1) * 8 / ADCClock
	 *     Startup time = (7 + 1) * 8 / 6.4MHz = 10 us
	 */
	adc12b_init(ADC12B, sysclk_get_cpu_hz(), 6400000, STARTUP_TIME, OFF_MODE_STARTUP_TIME);
#else
	/* Formula:
	 *     Startup  Time = (startup value + 1) * 8 / ADCClock
	 *     Startup time = (3 + 1) * 8 / 3.2MHz = 10 us
	 */
	adc_init(ADC, sysclk_get_cpu_hz(), 3200000, STARTUP_TIME);
#endif
#endif

	memset((void *)&g_adc_sample_data, 0, sizeof(g_adc_sample_data));

	/* Set ADC timing. */
#if SAM3S ||  SAM3XA || SAM4S
	/* Formula:
	 *     Transfer Time = (TRANSFER * 2 + 3) / ADCClock
	 *     Tracking Time = (TRACKTIM + 1) / ADCClock
	 *     Settling Time = settling value / ADCClock
	 *
	 *     Transfer Time = (1 * 2 + 3) / 6.4MHz = 781 ns
	 *     Tracking Time = (1 + 1) / 6.4MHz = 312 ns
	 *     Settling Time = 3 / 6.4MHz = 469 ns
	 */
	adc_configure_timing(ADC, TRACKING_TIME, ADC_SETTLING_TIME_3, TRANSFER_PERIOD);
#elif  SAM3N || SAM4C
	adc_configure_timing(ADC, TRACKING_TIME);
#elif SAM3U
	/* Formula:
	 *     Sample & Hold Time = SHTIM/ADCClock
	 *
	 *     Sample & Hold Time = 6 / 6.4 = 938 ns
	 */
#ifdef ADC_12B
	adc12b_configure_timing(ADC12B, SAMPLE_HOLD_TIME);
#else
	adc_configure_timing(ADC, SAMPLE_HOLD_TIME);
#endif
#endif

#if SAM3S || SAM3N || SAM3XA || SAM4S || SAM4C
	/* Enable channel number tag. */
	adc_enable_tag(ADC);
	/* Enable/disable sequencer. */
	if (g_adc_test_mode.uc_sequence_en) {
		/* Set user defined channel sequence. */
		adc_configure_sequence(ADC, ch_list, 2);

		/* Enable sequencer. */
		adc_start_sequencer(ADC);

		/* Enable channels. */
		for (i = 0; i < 2; i++) {
			adc_enable_channel(ADC, (enum adc_channel_num_t)i);
		}
		/* Update channel number. */
		g_adc_sample_data.uc_ch_num[0] = ch_list[0];
		g_adc_sample_data.uc_ch_num[1] = ch_list[1];
	} else {
		/* Disable sequencer. */
		adc_stop_sequencer(ADC);

		/* Enable channels. */
		adc_enable_channel(ADC, ADC_CHANNEL_POTENTIOMETER);
#if SAM3S || SAM3XA || SAM4S || SAM4C
		adc_enable_channel(ADC, ADC_TEMPERATURE_SENSOR);
#endif
		/* Update channel number. */
		g_adc_sample_data.uc_ch_num[0] = ADC_CHANNEL_POTENTIOMETER;
#if SAM3S || SAM3XA || SAM4S || SAM4C
		g_adc_sample_data.uc_ch_num[1] = ADC_TEMPERATURE_SENSOR;
#else
		g_adc_sample_data.uc_ch_num[1] = ADC_CHANNEL_POTENTIOMETER;
#endif
	}
#elif SAM3U
#ifdef ADC_12B
	adc12b_enable_channel(ADC12B, ADC_CHANNEL_POTENTIOMETER);
#else
	adc_enable_channel(ADC, ADC_CHANNEL_POTENTIOMETER);
#endif
	g_adc_sample_data.uc_ch_num[0] = ADC_CHANNEL_POTENTIOMETER;
	g_adc_sample_data.uc_ch_num[1] = ADC_CHANNEL_POTENTIOMETER;
#endif

#if SAM3S ||  SAM3XA || SAM4S || SAM4C
	/* Enable the temperature sensor. */
	adc_enable_ts(ADC);
#endif
	/* Set gain and offset (only single ended mode used here). */
#if SAM3S || SAM3XA || SAM4S
	adc_disable_anch(ADC); /* Disable analog change. */
#endif
	if (g_adc_test_mode.uc_gain_en) {
#if SAM3S || SAM3XA || SAM4S
		adc_enable_anch(ADC);
		/* gain = 2 */
		adc_set_channel_input_gain(ADC, ADC_CHANNEL_POTENTIOMETER, ADC_GAINVALUE_2);
#elif SAM3U
#ifdef ADC_12B
		adc12b_set_input_gain(ADC12B, ADC_GAINVALUE_2);
#endif
#endif
	} else {
#if SAM3S || SAM3XA || SAM4S
		/* gain = 1 */
		adc_set_channel_input_gain(ADC, ADC_CHANNEL_POTENTIOMETER, ADC_GAINVALUE_0);
#elif SAM3U
#ifdef ADC_12B
		adc12b_set_input_gain(ADC12B, ADC_GAINVALUE_0);
#endif
#endif
	}

	if (g_adc_test_mode.uc_offset_en) {
#if SAM3S || SAM3XA || SAM4S
		adc_enable_anch(ADC);
		adc_enable_channel_input_offset(ADC, ADC_CHANNEL_POTENTIOMETER);
#elif 	SAM3U
#ifdef ADC_12B
		adc12b_enable_input_offset(ADC12B);
#endif
#endif
	} else {
#if SAM3S || SAM3XA || SAM4S
		adc_disable_channel_input_offset(ADC, ADC_CHANNEL_POTENTIOMETER);
#elif 	SAM3U
#ifdef ADC_12B
		adc12b_disable_input_offset(ADC12B);
#endif
#endif
	}
	/* Set Auto Calibration Mode. */
#if  SAM3S8 || SAM3SD8 || SAM4S
	if (g_adc_test_mode.uc_auto_calib_en) {
		adc_set_calibmode(ADC);
		while (1) {
			if ((adc_get_status(ADC) & ADC_ISR_EOCAL) ==
					ADC_ISR_EOCAL)
				break;
		}
	}
#endif

#if SAM3S8 || SAM4S || SAM3N || SAM3SD8
	/* Set power save. */
	if (g_adc_test_mode.uc_power_save_en) {
		adc_configure_power_save(ADC, 1, 0);
	} else {
		adc_configure_power_save(ADC, 0, 0);;
	}
#elif SAM3U || SAM4C
#ifdef ADC_12B
	/* Set power save. */
	if (g_adc_test_mode.uc_power_save_en) {
		adc12b_configure_power_save(ADC12B, 1, 0);
	} else {
		adc12b_configure_power_save(ADC12B, 0, 0);;
	}

#else
	/* Set power save. */
	if (g_adc_test_mode.uc_power_save_en) {
		adc_configure_power_save(ADC, 1);
	} else {
		adc_configure_power_save(ADC, 0);;
	}
#endif
#endif

#if SAM3S || SAM3N || SAM3XA || SAM4S || SAM4C
	/* Transfer with/without PDC. */
	if (g_adc_test_mode.uc_pdc_en) {
		adc_read_buffer(ADC, g_adc_sample_data.us_value, BUFFER_SIZE);
		/* Enable PDC channel interrupt. */
		adc_enable_interrupt(ADC, ADC_IER_RXBUFF);
	} else {
		/* Enable Data ready interrupt. */
		adc_enable_interrupt(ADC, ADC_IER_DRDY);
	}
	/* Enable ADC interrupt. */
	NVIC_EnableIRQ(ADC_IRQn);
#elif SAM3U
#ifdef ADC_12B
	/* Transfer with/without PDC. */
	if (g_adc_test_mode.uc_pdc_en) {
		adc12_read_buffer(ADC12B, g_adc_sample_data.us_value, BUFFER_SIZE);
		/* Enable PDC channel interrupt. */
		adc12b_enable_interrupt(ADC12B, ADC12B_IER_RXBUFF);
	} else {
		/* Enable Data ready interrupt. */
		adc12b_enable_interrupt(ADC12B, ADC12B_IER_DRDY);

	}
	/* Enable ADC interrupt. */
	NVIC_EnableIRQ(ADC12B_IRQn);
#else
	/* Transfer with/without PDC. */
	if (g_adc_test_mode.uc_pdc_en) {
		adc_read_buffer(ADC, g_adc_sample_data.us_value, BUFFER_SIZE);
		/* Enable PDC channel interrupt. */
		adc_enable_interrupt(ADC, ADC_IER_RXBUFF);
	} else {
		/* Enable Data ready interrupt. */
		adc_enable_interrupt(ADC, ADC_IER_DRDY);

	}
	/* Enable ADC interrupt. */
	NVIC_EnableIRQ(ADC_IRQn);
#endif
#endif
	/* Configure trigger mode and start convention. */
	switch (g_adc_test_mode.uc_trigger_mode) {
	case TRIGGER_MODE_SOFTWARE:
#if SAM3S || SAM3N || SAM3XA || SAM4S || SAM4C
		adc_configure_trigger(ADC, ADC_TRIG_SW, 0);	/* Disable hardware trigger. */
#elif SAM3U
#ifdef ADC_12B
		adc12b_configure_trigger(ADC12B, ADC12B_TRIG_SW);
#else
		adc_configure_trigger(ADC, ADC_TRIG_SW);
#endif
#endif
		break;

	case TRIGGER_MODE_ADTRG:
#if SAM3S || SAM3N || SAM3XA || SAM4S || SAM4C
		gpio_configure_pin(PINS_ADC_TRIG, PINS_ADC_TRIG_FLAG);
		adc_configure_trigger(ADC, ADC_TRIG_EXT, 0);
#elif SAM3U
#ifdef ADC_12B
		gpio_configure_pin(PINS_ADC12B_TRIG, PINS_ADC12B_TRIG_FLAG);
		adc12b_configure_trigger(ADC12B, ADC12B_TRIG_EXT);
#else
		gpio_configure_pin(PINS_ADC_TRIG, PINS_ADC_TRIG_FLAG);
		adc_configure_trigger(ADC, ADC_TRIG_EXT);
#endif
#endif
		break;

	case TRIGGER_MODE_TIMER:
		configure_time_trigger();
		break;
#if SAM3S || SAM3U || SAM3XA || SAM4S
	case TRIGGER_MODE_PWM:
		configure_pwm_trigger();
		break;
#endif
#if SAM3S || SAM3N || SAM3XA || SAM4S || SAM4C
	case TRIGGER_MODE_FREERUN:
		adc_configure_trigger(ADC, ADC_TRIG_SW, 1);
		break;
#endif
	default:
		break;
	}
}

/**
 * \brief Systick handler.
 */
void SysTick_Handler(void)
{
	gs_ul_ms_ticks++;
}

#if SAM3S || SAM3N || SAM3XA || SAM4S || SAM4C
/**
 * \brief Interrupt handler for the ADC.
 */
void ADC_Handler(void)
{
	uint32_t i;
	uint32_t ul_temp;
	uint8_t uc_ch_num;

	/* With PDC transfer */
	if (g_adc_test_mode.uc_pdc_en) {
		if ((adc_get_status(ADC) & ADC_ISR_RXBUFF) ==
				ADC_ISR_RXBUFF) {
			g_adc_sample_data.us_done = ADC_DONE_MASK;
			adc_read_buffer(ADC, g_adc_sample_data.us_value, BUFFER_SIZE);
			/* Only keep sample value, and discard channel number. */
			for (i = 0; i < NUM_CHANNELS; i++) {
				g_adc_sample_data.us_value[i] &= ADC_LCDR_LDATA_Msk;
			}
		}
	} else {	/* Without PDC transfer */
		if ((adc_get_status(ADC) & ADC_ISR_DRDY) ==
				ADC_ISR_DRDY) {
			ul_temp = adc_get_latest_value(ADC);
			for (i = 0; i < NUM_CHANNELS; i++) {
				uc_ch_num = (ul_temp & ADC_LCDR_CHNB_Msk) >>
						ADC_LCDR_CHNB_Pos;
				if (g_adc_sample_data.uc_ch_num[i] == uc_ch_num) {
					g_adc_sample_data.us_value[i] =
							ul_temp &
							ADC_LCDR_LDATA_Msk;
					g_adc_sample_data.us_done |= 1 << i;
				}
			}
		}
	}
}
Exemplo n.º 27
0
/**
 *  \brief ACC example application entry point.
 *
 *  \return Unused (ANSI-C compatibility).
 */
int main(void)
{
	uint8_t uc_key;
	int16_t s_volt = 0;
	uint32_t ul_value = 0;
	volatile uint32_t ul_status = 0x0;
	int32_t l_volt_dac0 = 0;

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

	/* Initialize debug console */
	configure_console();

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

	/* Initialize DACC */
	/* Enable clock for DACC */
	pmc_enable_periph_clk(ID_DACC);
	/* Reset DACC registers */
	dacc_reset(DACC);
	/* External trigger mode disabled. DACC in free running mode. */
	dacc_disable_trigger(DACC);
	/* Half word transfer mode */
	dacc_set_transfer_mode(DACC, 0);
	/* Power save:
	 * sleep mode  - 0 (disabled)
	 * fast wake-up - 0 (disabled)
	 */
	dacc_set_power_save(DACC, 0, 0);
	/* Timing:
	 * refresh        - 0x08 (1024*8 dacc clocks)
	 * max speed mode -    0 (disabled)
	 * startup time   - 0xf (960 dacc clocks)
	 */
	dacc_set_timing(DACC, 0x08, 0, 0xf);
	/* Disable TAG and select output channel DACC_CHANNEL */
	dacc_set_channel_selection(DACC, DACC_CHANNEL_0);
	/* Enable output channel DACC_CHANNEL */
	dacc_enable_channel(DACC, DACC_CHANNEL_0);
	/* Setup analog current */
	dacc_set_analog_control(DACC, DACC_ANALOG_CONTROL);

	/* Set DAC0 output at ADVREF/2. The DAC formula is:
	 *
	 * (5/6 * VOLT_REF) - (1/6 * VOLT_REF)     volt - (1/6 * VOLT_REF)
	 * ----------------------------------- = --------------------------
	 *              MAX_DIGITAL                       digit
	 *
	 * Here, digit = MAX_DIGITAL/2
	 */
	dacc_write_conversion_data(DACC, MAX_DIGITAL / 2);
	l_volt_dac0 = (MAX_DIGITAL / 2) * (2 * VOLT_REF / 3) / MAX_DIGITAL +
			VOLT_REF / 6;

	/* Initialize ADC */
	/* Enable clock for ADC */
	pmc_enable_periph_clk(ID_ADC);
	/*
	 * Formula: ADCClock = MCK / ( (PRESCAL+1) * 2 )
	 * For example, MCK = 64MHZ, PRESCAL = 4, then:
	 *     ADCClock = 64 / ((4+1) * 2) = 6.4MHz;
	 */
	adc_init(ADC, sysclk_get_cpu_hz(), ADC_CLOCK, ADC_STARTUP_TIME_SETTING);

	/* Formula:
	 *     Startup  Time = startup value / ADCClock
	 *     Transfer Time = (TRANSFER * 2 + 3) / ADCClock
	 *     Tracking Time = (TRACKTIM + 1) / ADCClock
	 *     Settling Time = settling value / ADCClock
	 * For example, ADC clock = 6MHz (166.7 ns)
	 *     Startup time = 512 / 6MHz = 85.3 us
	 *     Transfer Time = (1 * 2 + 3) / 6MHz = 833.3 ns
	 *     Tracking Time = (0 + 1) / 6MHz = 166.7 ns
	 *     Settling Time = 3 / 6MHz = 500 ns
	 */
	/* Set ADC timing */
	adc_configure_timing(ADC, ADC_TRACK_SETTING, ADC_SETTLING_TIME_3,
			ADC_TRANSFER_SETTING);

	/* Channel 5 has to be compared */
	adc_enable_channel(ADC, ADC_CHANNEL_5);

	//! [acc_enable_clock]
	/** Enable clock for ACC */
	pmc_enable_periph_clk(ID_ACC);
	//! [acc_enable_clock]

	//! [acc_init]
	/** Initialize ACC */
	acc_init(ACC, ACC_MR_SELPLUS_AD5, ACC_MR_SELMINUS_DAC0,
			ACC_MR_EDGETYP_ANY, ACC_MR_INV_DIS);
	//! [acc_init]

	//! [acc_irq_enable]
	/** Enable ACC interrupt */
	NVIC_EnableIRQ(ACC_IRQn);

	/** Enable */
	acc_enable_interrupt(ACC);
	//! [acc_irq_enable]

	dsplay_menu();

	while (1) {
		while (uart_read(CONSOLE_UART, &uc_key)) {
		}

		printf("input: %c\r\n", uc_key);

		switch (uc_key) {
		case 's':
		case 'S':
			printf("Input DAC0 output voltage (%d~%d mv): ",
					(VOLT_REF / 6), (VOLT_REF * 5 / 6));
			s_volt = get_input_voltage();
			puts("\r");

			if (s_volt > 0) {
				l_volt_dac0 = s_volt;
				/* The DAC formula is:
				 *
				 * (5/6 * VOLT_REF) - (1/6 * VOLT_REF)     volt - (1/6 * VOLT_REF)
				 * ----------------------------------- = --------------------------
				 *              MAX_DIGITAL                       digit
				 *
				 */
				ul_value = ((s_volt - (VOLT_REF / 6))
					* (MAX_DIGITAL * 6) / 4) / VOLT_REF;
				dacc_write_conversion_data(DACC, ul_value);
				puts("-I- Set ok\r");
			} else {
				puts("-I- Input voltage is invalid\r");
			}
			break;
		case 'v':
		case 'V':
			/* Start conversion */
			adc_start(ADC);
			ul_status = adc_get_status(ADC);
			while ((ul_status & ADC_ISR_EOC5) != ADC_ISR_EOC5) {
				ul_status = adc_get_status(ADC);
			}
			/* Conversion is done */
			ul_value = adc_get_channel_value(ADC, ADC_CHANNEL_5);

			/*
			 * Convert ADC sample data to voltage value:
			 * voltage value = (sample data / max. resolution) * reference voltage
			 */
			s_volt = (ul_value * VOLT_REF) / MAX_DIGITAL;
			printf("-I- Voltage on potentiometer(AD5) is %d mv\n\r", s_volt);
			printf("-I- Voltage on DAC0 is %ld mv \n\r", (long)l_volt_dac0);
			break;
			
		case 'm':
		case 'M':
			dsplay_menu();
			break;
		}
	}
}