Beispiel #1
0
/**
 * \brief Configure to trigger ADC by TIOA output of timer.
 */
static void configure_time_trigger(void)
{
	uint32_t ul_div = 0;
	uint32_t ul_tc_clks = 0;
	uint32_t ul_sysclk = sysclk_get_cpu_hz();

	/* Enable peripheral clock. */
	pmc_enable_periph_clk(ID_TC0);

	/* TIOA configuration */
	gpio_configure_pin(PIN_TC0_TIOA0, PIN_TC0_TIOA0_FLAGS);

	/* Configure TC for a 1Hz frequency and trigger on RC compare. */
	tc_find_mck_divisor(1, ul_sysclk, &ul_div, &ul_tc_clks, ul_sysclk);
	tc_init(TC0, 0, ul_tc_clks | TC_CMR_CPCTRG | TC_CMR_WAVE |
			TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_SET);
	TC0->TC_CHANNEL[0].TC_RA = (ul_sysclk / ul_div) / 2;
	TC0->TC_CHANNEL[0].TC_RC = (ul_sysclk / ul_div) / 1;

	/* Start the Timer. */
	tc_start(TC0, 0);
	/* Set TIOA0 trigger. */
#if SAM3S || SAM3N || SAM3XA || SAM4S || SAM4C
	adc_configure_trigger(ADC, ADC_TRIG_TIO_CH_0, 0);
#elif SAM3U
#ifdef ADC_12B
	adc12b_configure_trigger(ADC12B, ADC12B_TRIG_TIO_CH_0);
#else
	adc_configure_trigger(ADC, ADC_TRIG_TIO_CH_0);
#endif
#endif
}
Beispiel #2
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();
}
Beispiel #3
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();
}
Beispiel #4
0
/* Initialize ADC for reading sensors */
void hal_adc_init(void)
{
	/* Enable peripheral clock. */
#if SAM3S || SAM3N || SAM3XA || SAM4S
	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. */
#if SAM3S || SAM3N || SAM3XA || SAM4S
  adc_init(ADC, SystemCoreClock, ADC_FREQ_MAX, ADC_STARTUP_FAST);
#elif SAM3U
  #ifdef ADC_12B
    adc12b_init(ADC12B, sysclk_get_cpu_hz(), 6400000, 10, 10);
  #else
    adc_init(ADC, sysclk_get_cpu_hz(), 6400000, 10);
  #endif
#endif


//
  adc_configure_timing(ADC, 0, ADC_SETTLING_TIME_3, 1);
  adc_configure_trigger(ADC, ADC_TRIG_SW, 0); // Disable hardware trigger.
  adc_disable_interrupt(ADC, 0xFFFFFFFF); // Disable all ADC interrupts.
  adc_disable_all_channel(ADC);

}
Beispiel #5
0
// Module initialisation
void AnalogInInit()
{
#if SAM3XA || SAM4S
	pmc_enable_periph_clk(ID_ADC);
	adc_init(ADC, SystemCoreClock, 2000000, ADC_STARTUP_TIME_12);	// 2MHz clock
	adc_configure_timing(ADC, 3, ADC_SETTLING_TIME_3, 1);			// Add transfer time
	adc_configure_trigger(ADC, ADC_TRIG_SW, 0);						// Disable hardware trigger
	adc_disable_interrupt(ADC, 0xFFFFFFFF);							// Disable all ADC interrupts
	adc_disable_all_channel(ADC);
#elif SAM4E || SAME70
	afec_enable(AFEC0);
	afec_enable(AFEC1);
	afec_config cfg;
	afec_get_config_defaults(&cfg);

#if 0	// these are probably not needed, the defaults should be OK
//	cfg.afec_clock = 2000000UL;						// reduce clock frequency
//	cfg.settling_time = AFEC_SETTLING_TIME_3;
#endif

	while (afec_init(AFEC0, &cfg) != STATUS_OK)
	{
		(void)afec_get_latest_value(AFEC0);
	}
	while (afec_init(AFEC1, &cfg) != STATUS_OK)
	{
		(void)afec_get_latest_value(AFEC1);
	}
	afec_disable_interrupt(AFEC0, AFEC_INTERRUPT_ALL);
	afec_disable_interrupt(AFEC1, AFEC_INTERRUPT_ALL);
	afec_set_trigger(AFEC0, AFEC_TRIG_SW);
	afec_set_trigger(AFEC1, AFEC_TRIG_SW);
#endif
}
/* 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);
}
Beispiel #7
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) {
	}
}
 /**************************************************************************
 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);
 }
Beispiel #9
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);
}
Beispiel #10
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);
}
Beispiel #11
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);
Beispiel #12
0
/*
 * Initializing A/D conversion.
 */
void adc_setup(void)
{
	/* Enable the specified peripheral clock (ADC clock).
	   If function returns 0, then we can proceed... */
		pmc_enable_periph_clk(ID_ADC);
		/* init A/D conversion */
		adc_init(ADC, sysclk_get_main_hz(), ADC_CLOCK, 8);
		/* configure timing for A/D conversion */
		adc_configure_timing(ADC, 0, ADC_SETTLING_TIME_3, 1);
		/* set 12 bit resolution */
		adc_set_resolution(ADC, ADC_MR_LOWRES_BITS_12);
		/* enable ADC channel - specified in 'adc.h' */
		/*adc_enable_channel(ADC, ADC_CHANNEL_LCDButtons);
		adc_enable_channel(ADC, ADC_CHANNEL_Tank1);
 		adc_enable_channel(ADC, ADC_CHANNEL_Tank2);*/
		ADC->ADC_CHER = 3200;
		
		/* configure conversion to be triggered by software */
		adc_configure_trigger(ADC, ADC_TRIG_SW, 0);
		/* indicate everything's OK! */
}
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 */
}
Beispiel #14
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 = 500;
	gs_us_high_threshold = 2000;

	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 0.625*VCC */
		.refsel = ADC_REFSEL_1,
		/* 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 500 * VOLT_REF / 4095 = 251mv. */
		.low_threshold = gs_us_low_threshold,
		/* The equivalent voltage value is 2000 * VOLT_REF / 4095 = 1002mv. */
		.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");
	}
}
void init( void )
{
    SystemInit();

    // Set Systick to 1ms interval
    if (SysTick_Config(SystemCoreClock / 1000))
    {
        // Capture error
        while (true);
    }

    // Disable watchdog
    WDT_Disable(WDT);

    // Initialize C library
    __libc_init_array();

    // Disable pull-up on every pin
    for (uint i = 0u; i < PINS_COUNT; i++)
        digitalWrite(i, LOW);

    // Enable parallel access on PIO output data registers
    PIOA->PIO_OWER = 0xFFFFFFFF;
    PIOB->PIO_OWER = 0xFFFFFFFF;
    //PIOC->PIO_OWER = 0xFFFFFFFF;
    //PIOD->PIO_OWER = 0xFFFFFFFF;


    //turn off ERASE and JTAG pins
    MATRIX->CCFG_SYSIO = CCFG_SYSIO_SYSIO12 | CCFG_SYSIO_SYSIO7 | CCFG_SYSIO_SYSIO6 | CCFG_SYSIO_SYSIO5 | CCFG_SYSIO_SYSIO4;

// Initialize Serial port UART pins
    PIO_Configure(
        g_APinDescription[PINS_USART0].pPort,
        g_APinDescription[PINS_USART0].ulPinType,
        g_APinDescription[PINS_USART0].ulPin,
        g_APinDescription[PINS_USART0].ulPinConfiguration);
    digitalWrite(0u, HIGH); // Enable pullup for RX0

    // Initialize Serial port USART pins
    // Pins are disconnected from PIO controller and hooked to the peripheral.
    // Currently PIO_Configure always enables the pullup resistor for peripherals. This appears to be a bug, as it is not written correctly for that purpose, but has that affect.
    PIO_Configure(
        g_APinDescription[PINS_UART1].pPort,
        g_APinDescription[PINS_UART1].ulPinType,
        g_APinDescription[PINS_UART1].ulPin,
        g_APinDescription[PINS_UART1].ulPinConfiguration);

    PIO_Configure(
        g_APinDescription[B1].pPort,
        g_APinDescription[B1].ulPinType,
        g_APinDescription[B1].ulPin,
        g_APinDescription[B1].ulPinConfiguration);

    /*
    TODO: wire up USB ID line and check out USB configuration
     // Initialize USB pins
     PIO_Configure(
       g_APinDescription[PINS_USB].pPort,
       g_APinDescription[PINS_USB].ulPinType,
       g_APinDescription[PINS_USB].ulPin,
       g_APinDescription[PINS_USB].ulPinConfiguration);


    //TODO: Initialize I2C pins for crypto IC
     PIO_Configure(
       g_APinDescription[PINS_SPI].pPort,
       g_APinDescription[PINS_SPI].ulPinType,
       g_APinDescription[PINS_SPI].ulPin,
       g_APinDescription[PINS_SPI].ulPinConfiguration);
    */

    // Initialize Analog Controller
    pmc_enable_periph_clk(ID_ADC);
    adc_init(ADC, SystemCoreClock, ADC_FREQ_MAX, ADC_STARTUP_FAST);
    adc_configure_timing(ADC, 0, ADC_SETTLING_TIME_3, 1);
    adc_configure_trigger(ADC, ADC_TRIG_SW, 0); // Disable hardware trigger.
    adc_disable_interrupt(ADC, 0xFFFFFFFF); // Disable all ADC interrupts.
    adc_disable_all_channel(ADC);

    // Initialize analogOutput module
    analogOutputInit();
}
Beispiel #16
0
/**
* \brief Initialize the temperature sensor
*/
void initialize_temperature(void) {

/** not used at present   */
#if 0
	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 VCC/2 */
		.refsel =ADC_REFSEL_4,
		/* 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,
		/* Temperature sensor */
		.muxpos = EPD_Temperature_Sensor_ADC,
		/* Enables the internal voltage sources */
		.internal =ADC_INTERNAL_2,
		/* Disables the ADC gain error reduction */
		.gcomp = ADC_GCOMP_DIS,
		/* Disables the HWLA mode */
		.hwla = ADC_HWLA_DIS,
		.gain=ADC_GAIN_1X,
		/* 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 = 0,
		.low_threshold = 0,
		.high_threshold = 0,
	};

	adc_init(&g_adc_inst, ADCIFE, &adc_cfg);
	adc_enable(&g_adc_inst);
	adc_ch_set_config(&g_adc_inst, &adc_ch_cfg);
	adc_set_callback(&g_adc_inst, ADC_SEQ_SEOC, adcife_read_conv_result, ADCIFE_IRQn, 1);
	adc_configure_trigger(&g_adc_inst,ADC_TRIG_SW);
	adc_configure_gain(&g_adc_inst, ADC_GAIN_1X);
#endif
	
}


/**
* \brief Initialize the EPD hardware setting
*/
void EPD_display_hardware_init (void) {
	EPD_initialize_gpio();
	EPD_Vcc_turn_off();
	epd_spi_init();
	initialize_temperature();
	EPD_cs_low();
	EPD_pwm_low();
	EPD_rst_low();
	EPD_discharge_low();
	EPD_border_low();
	//initialize_EPD_timer();
}
Beispiel #17
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;
				}
			}
		}
	}
}
Beispiel #18
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");
	}
}
void init( void )
{
  SystemInit();

  // Set Systick to 1ms interval, common to all SAM3 variants
  if (SysTick_Config(SystemCoreClock / 1000))
  {
    // Capture error
    while (true);
  }

  // Disable watchdog
  WDT_Disable(WDT);

  // Initialize C library
  __libc_init_array();

  // Disable pull-up on every pin
  for (int i = 0; i < PINS_COUNT; i++)
      digitalWrite(i, LOW);

  // Enable parallel access on PIO output data registers
  PIOA->PIO_OWER = 0xFFFFFFFF;
  PIOB->PIO_OWER = 0xFFFFFFFF;
  PIOC->PIO_OWER = 0xFFFFFFFF;
  PIOD->PIO_OWER = 0xFFFFFFFF;

  // Initialize Serial port U(S)ART pins
  PIO_Configure(
    g_APinDescription[PINS_UART].pPort,
    g_APinDescription[PINS_UART].ulPinType,
    g_APinDescription[PINS_UART].ulPin,
    g_APinDescription[PINS_UART].ulPinConfiguration);
  digitalWrite(0, HIGH); // Enable pullup for RX0
  PIO_Configure(
    g_APinDescription[PINS_USART0].pPort,
    g_APinDescription[PINS_USART0].ulPinType,
    g_APinDescription[PINS_USART0].ulPin,
    g_APinDescription[PINS_USART0].ulPinConfiguration);
  PIO_Configure(
    g_APinDescription[PINS_USART1].pPort,
    g_APinDescription[PINS_USART1].ulPinType,
    g_APinDescription[PINS_USART1].ulPin,
    g_APinDescription[PINS_USART1].ulPinConfiguration);
  PIO_Configure(
    g_APinDescription[PINS_USART3].pPort,
    g_APinDescription[PINS_USART3].ulPinType,
    g_APinDescription[PINS_USART3].ulPin,
    g_APinDescription[PINS_USART3].ulPinConfiguration);

  // Initialize USB pins
  PIO_Configure(
    g_APinDescription[PINS_USB].pPort,
    g_APinDescription[PINS_USB].ulPinType,
    g_APinDescription[PINS_USB].ulPin,
    g_APinDescription[PINS_USB].ulPinConfiguration);

  // Initialize CAN pins
 /* PIO_Configure(
    g_APinDescription[PINS_CAN0].pPort,
    g_APinDescription[PINS_CAN0].ulPinType,
    g_APinDescription[PINS_CAN0].ulPin,
    g_APinDescription[PINS_CAN0].ulPinConfiguration);
  PIO_Configure(
    g_APinDescription[PINS_CAN1].pPort,
    g_APinDescription[PINS_CAN1].ulPinType,
    g_APinDescription[PINS_CAN1].ulPin,
    g_APinDescription[PINS_CAN1].ulPinConfiguration); */

  // Initialize Analog Controller
  pmc_enable_periph_clk(ID_ADC);
  adc_init(ADC, SystemCoreClock, ADC_FREQ_MAX, ADC_STARTUP_FAST);
  adc_configure_timing(ADC, 0, ADC_SETTLING_TIME_3, 1);
  adc_configure_trigger(ADC, ADC_TRIG_SW, 0); // Disable hardware trigger.
  adc_disable_interrupt(ADC, 0xFFFFFFFF); // Disable all ADC interrupts.
  adc_disable_all_channel(ADC);

  // Initialize analogOutput module
  analogOutputInit();
}
Beispiel #20
0
/**
 * \brief Start ADC sample.
 * Initialize ADC, set clock and timing, and set ADC to given mode.
 */
static void start_adc(void)
{
	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 0.625*VCC */
		.refsel = ADC_REFSEL_1,
		/* 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 = 0,
		.low_threshold = 0,
		.high_threshold = 0,
	};
	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);
	}

	if (g_adc_test_mode.uc_pdc_en) {
		adc_disable_interrupt(&g_adc_inst, ADC_SEQ_SEOC);
		adc_pdca_set_config(&g_adc_pdca_cfg);
		pdca_channel_set_callback(CONFIG_ADC_PDCA_RX_CHANNEL, pdca_transfer_done,
				PDCA_0_IRQn, 1, PDCA_IER_TRC);
	} else {
		pdca_channel_disable_interrupt(CONFIG_ADC_PDCA_RX_CHANNEL,
				PDCA_IDR_TRC);
		pdca_channel_disable_interrupt(CONFIG_ADC_PDCA_TX_CHANNEL,
				PDCA_IDR_TRC);
		adc_ch_set_config(&g_adc_inst, &adc_ch_cfg);
		adc_set_callback(&g_adc_inst, ADC_SEQ_SEOC, adcife_read_conv_result,
				ADCIFE_IRQn, 1);
	}

	/* Configure trigger mode and start convention. */
	switch (g_adc_test_mode.uc_trigger_mode) {
	case TRIGGER_MODE_SOFTWARE:
		adc_configure_trigger(&g_adc_inst, ADC_TRIG_SW);
		break;
	case TRIGGER_MODE_CON:
		adc_configure_trigger(&g_adc_inst, ADC_TRIG_CON);
		break;
	case TRIGGER_MODE_ITIMER:
		adc_configure_trigger(&g_adc_inst, ADC_TRIG_INTL_TIMER);
		adc_configure_itimer_period(&g_adc_inst,
				adc_ch_cfg.internal_timer_max_count);
		adc_start_itimer(&g_adc_inst);
		break;
	default:
		break;
	}

	if (g_adc_test_mode.uc_gain_en) {
		adc_configure_gain(&g_adc_inst, ADC_GAIN_2X);
	} else {
		adc_configure_gain(&g_adc_inst, ADC_GAIN_1X);
	}
}

/**
 * \brief Start DAC ouput.
 * Initialize DAC, set clock and timing, and set DAC to given mode.
 */
static void start_dac(void)
{
	sysclk_enable_peripheral_clock(DACC);

	/* Reset DACC registers */
	dacc_reset(DACC);

	/* Half word transfer mode */
	dacc_set_transfer_mode(DACC, 0);

	/* Timing:
	 * startup                - 0x10 (17 clocks)
	 * internal trigger clock - 0x60 (96 clocks)
	 */
	dacc_set_timing(DACC, 0x10, 0x60);

	/* Enable DAC */
	dacc_enable(DACC);

	/* The DAC is 10-bit resolution, so output voltage should be
	 * (3300 * 255) / ((1 << 10) - 1) = 823mv */
	dacc_write_conversion_data(DACC, 0xFF);
}
Beispiel #21
0
/**
 * \brief Test ADCIFE in Differential mode.
 *
 * \param test Current test case.
 */
static void run_adcife_diff_test(const struct test_case *test)
{
	uint32_t timeout = ADC_NUM_OF_ATTEMPTS;
	bool conversion_timeout = false;

	struct adc_seq_config adc_seq_cfg = {
		/* Select Vref for shift cycle */
		.zoomrange = ADC_ZOOMRANGE_0,
		/* Pad Ground */
		.muxneg = ADC_MUXNEG_1,
		/* Scaled Vcc, Vcc/10 */
		.muxpos = ADC_MUXPOS_2,
		/* 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 differential mode */
		.bipolar = ADC_BIPOLAR_DIFFERENTIAL
	};
	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 = 0,
		.low_threshold = 0,
		.high_threshold = 0,
	};

	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);
	while (!((adc_get_status(&g_adc_inst) & ADCIFE_SR_SEOC) ==
			ADCIFE_SR_SEOC)) {
		if (!timeout--) {
			conversion_timeout = true;
		}
	}

	test_assert_true(test, conversion_timeout == false, "ADCIFE Differential conversion timeout");

	/* Because selected channel is positive input, then in differential mode
	 * the output conversion result will = 2047 + (Vin/Vref)*2047.
	 */
	test_assert_true(test, adc_get_last_conv_value(&g_adc_inst) > 2047,
			"ADCIFE Differential test failed");
}

/**
 * \brief Test ADCIFE in internal timer trigger mode,
 *        which also tests interrupt driven conversions.
 *
 * \param test Current test case.
 */
static void run_adcife_itimer_trig_test(const struct test_case *test)
{
	struct adc_seq_config adc_seq_cfg = {
		/* Select Vref for shift cycle */
		.zoomrange = ADC_ZOOMRANGE_0,
		/* Pad Ground */
		.muxneg = ADC_MUXNEG_1,
		/* Scaled Vcc, Vcc/10 */
		.muxpos = ADC_MUXPOS_2,
		/* 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 = 0,
		.low_threshold = 0,
		.high_threshold = 0,
	};

	adc_ch_set_config(&g_adc_inst, &adc_ch_cfg);
	adc_set_callback(&g_adc_inst, ADC_SEQ_SEOC, adcife_set_conv_flag,
			ADCIFE_IRQn, 1);
	adc_configure_trigger(&g_adc_inst, ADC_TRIG_INTL_TIMER);
	adc_configure_gain(&g_adc_inst, ADC_GAIN_1X);
	adc_configure_itimer_period(&g_adc_inst,
			adc_ch_cfg.internal_timer_max_count);
	adc_start_itimer(&g_adc_inst);
	delay_ms(100);

	test_assert_true(test, g_uc_condone_flag == 1,
			"ADCIFE Internal Timer trigger test failed");
}

/* When VDDANA is in MIN value = 2.4V, the equivalent voltage value is
 * (2400 * 255) / ((1 << 10) - 1) = 598mv. The relative digital value is
 * 598 * 4095 / 1000 = 2449. */
#define DAC_INTERNAL_MIN_VALUE          2449
/* When VDDANA is in MAX value = 3.6V the equivalent voltage value is
 * (3600 * 255) / ((1 << 10) - 1) = 897mv. The relative digital value is
 * 897 * 4095 / 1000 = 3673. */
#define DAC_INTERNAL_MAX_VALUE          3673
/* When VCC is in MIN value = 1.6V, the equivalent voltage value is
 * 1600 / 10 = 160mv. The relative digital value is
 * 160 * 4095 / 1000 = 434. */
#define VCC_SCALED_MIN_VALUE            434
/* When VCC is in MAX value = 3.6V, the equivalent voltage value is
 * 3600 / 10 = 360mv. The relative digital value is
 * 360 * 4095 / 1000 = 1474. */
#define VCC_SCALED_MAX_VALUE            1474

/**
 * \brief Test ADCIFE in multiple channel mode.
 *
 * \param test Current test case.
 */
static void run_adcife_multichannel_test(const struct test_case *test)
{
	start_dac();

	adc_pdca_set_config(&g_adc_pdca_cfg);
	pdca_channel_set_callback(CONFIG_ADC_PDCA_RX_CHANNEL, pdca_transfer_done,
			PDCA_0_IRQn, 1, PDCA_IER_TRC);
	adc_configure_trigger(&g_adc_inst, ADC_TRIG_CON);
	adc_configure_gain(&g_adc_inst, ADC_GAIN_1X);

	delay_ms(100);

	/* The DAC output voltage value is 823mv, so the equivalent ADC value should be
	 * 4095 * 823 / 1000 = 3370. The scaled VCC output voltage is 330mv, so the
	 * equivalent ADC value should be 4095 * 330 / 1000 =  1351. */
	test_assert_true(test,
			((DAC_INTERNAL_MIN_VALUE < g_adc_sample_data[0] < DAC_INTERNAL_MAX_VALUE)
			&& (VCC_SCALED_MIN_VALUE < g_adc_sample_data[1] < VCC_SCALED_MAX_VALUE)),
			"ADCIFE Multichannel test failed");
}

/**
 * \brief Test ADCIFE in window monitor mode.
 *
 * \param test Current test case.
 */
static void run_adcife_wm_test(const struct test_case *test)
{
	struct adc_seq_config adc_seq_cfg = {
		/* Select Vref for shift cycle */
		.zoomrange = ADC_ZOOMRANGE_0,
		/* Pad Ground */
		.muxneg = ADC_MUXNEG_1,
		/* Scaled Vcc, Vcc/10 */
		.muxpos = ADC_MUXPOS_2,
		/* 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 205 * 1000 / 4095 = 50mv. */
		.low_threshold = 205,
		/*  The equivalent voltage value is 2050 * 1000 / 4095 = 500mv. */
		.high_threshold = 2050,
	};

	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_set_wm_flag,
			ADCIFE_IRQn, 1);
	delay_ms(100);
	test_assert_true(test, g_uc_enter_win_flag == 1,
			"ADCIFE Inside Window Mode test failed");

	/* The teseted channel voltage is outside window */
	adc_disable(&g_adc_inst);
	g_uc_enter_win_flag = 0;
	adc_seq_cfg.muxpos = ADC_MUXPOS_3;
	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_enable_interrupt(&g_adc_inst, ADC_WINDOW_MONITOR);

	delay_ms(100);
	test_assert_true(test, g_uc_enter_win_flag == 0,
			"ADCIFE Outside Window Mode test failed");
}

/**
 * \brief Run ADCIFE driver unit tests.
 */
int main(void)
{
	const usart_serial_options_t usart_serial_options = {
		.baudrate = CONF_TEST_BAUDRATE,
		.charlength = CONF_TEST_CHARLENGTH,
		.paritytype = CONF_TEST_PARITY,
		.stopbits = CONF_TEST_STOPBITS
	};

	/* Initialize the system clock and board */
	sysclk_init();
	board_init();

	/* Enable the debug uart */
	stdio_serial_init(CONF_TEST_USART, &usart_serial_options);

#if defined(__GNUC__)
	setbuf(stdout, NULL);
#endif

	/* Define all the test cases */
	DEFINE_TEST_CASE(adcife_init_test, NULL, run_adcife_init_test, NULL,
			"ADCIFE Initialize test");
	DEFINE_TEST_CASE(adcife_diff_test, NULL, run_adcife_diff_test, NULL,
			"ADCIFE Differential test");
	DEFINE_TEST_CASE(adcife_itmer_trig_test, NULL, run_adcife_itimer_trig_test,
			NULL, "ADCIFE Internal Timer trigger test");
	DEFINE_TEST_CASE(adcife_multichannel_test, NULL, run_adcife_multichannel_test, NULL,
			"ADCIFE Multichannel test");
	DEFINE_TEST_CASE(adcife_wm_test, NULL, run_adcife_wm_test,
			NULL, "ADCIFE Window Monitor Mode test");

	/* Put test case addresses in an array */
	DEFINE_TEST_ARRAY(adcife_tests) = {
	&adcife_init_test,
	&adcife_diff_test,
	&adcife_itmer_trig_test,
	&adcife_multichannel_test,
	&adcife_wm_test,
	};

	/* Define the test suite */
	DEFINE_TEST_SUITE(adcife_suite, adcife_tests,
			"SAM ADCIFE driver test suite");

	/* Run all tests in the test suite */
	test_suite_run(&adcife_suite);

	while (1) {
		/* Busy-wait forever. */
	}
}