/** **************************************************************************************** * @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; }
/************************************************************************** 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); }
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; }
/** * \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(); }
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; }
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; }
/** * \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(); }
/* 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); }
/** * \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) { } }
/* * 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)); }
/** * \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); }
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); }
/* * 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)); }
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); }
// 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 } } }
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); }
/** * \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); }
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); }
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 */ }
/** * \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; } }
/** * \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"); } }
/** * \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; } } } } }
/** * \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; } } }