/** * \brief Callback function for ADCIFE enter compasion window interrupt. */ static void adcife_set_wm_flag(void) { /* Disable Window Monitor Interrupt. */ adc_disable_interrupt(&g_adc_inst, ADC_WINDOW_MONITOR); g_uc_enter_win_flag = 1; adc_clear_status(&g_adc_inst, ADCIFE_SCR_WM); }
/* 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); }
// 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 }
/** * \brief Callback function for ADCIFE interrupt. */ static void adcife_set_conv_flag(void) { if ((adc_get_status(&g_adc_inst) & ADCIFE_SR_SEOC) == ADCIFE_SR_SEOC) { g_uc_condone_flag = 1; adc_clear_status(&g_adc_inst, ADCIFE_SCR_SEOC); adc_disable_interrupt(&g_adc_inst, ADC_SEQ_SEOC); } }
/** * \brief Application entry point for adcife example. * * \return Unused (ANSI-C compatibility). */ int main(void) { uint32_t uc_key = 0; /* Initialize the SAM system */ sysclk_init(); board_init(); /* Initialize the UART console */ configure_console(); /* Output example information */ puts(STRING_HEADER); /* Set default ADCIFE test mode. */ g_adc_test_mode.uc_trigger_mode = TRIGGER_MODE_SOFTWARE; g_adc_test_mode.uc_pdc_en = 1; g_adc_test_mode.uc_gain_en = 0; display_menu(); start_dac(); start_adc(); while (1) { /* ADCIFE software trigger per 1s */ if (g_adc_test_mode.uc_trigger_mode == TRIGGER_MODE_SOFTWARE) { adc_start_software_conversion(&g_adc_inst); } if (!usart_read(CONF_UART, &uc_key)) { adc_disable_interrupt(&g_adc_inst, ADC_SEQ_SEOC); display_menu(); set_adc_test_mode(); start_adc(); puts("Press any key to display configuration menu.\r"); } delay_ms(1000); if (g_uc_condone_flag == 1) { if(g_adc_test_mode.uc_pdc_en == 0) { printf("Internal DAC Voltage = %4d mv \r\n", (int)(g_adc_sample_data[0] * VOLT_REF / MAX_DIGITAL)); } else { printf("Internal DAC Voltage = %4d mv \r\n", (int)(g_adc_sample_data[0] * VOLT_REF / MAX_DIGITAL)); printf("Scaled VCC Voltage = %4d mv \r\n", (int)(g_adc_sample_data[1] * VOLT_REF / MAX_DIGITAL)); } g_uc_condone_flag = 0; } } }
static void _adc_interrupt_handler(const uint8_t instance) { struct adc_module *module = _adc_instances[instance]; /* get interrupt flags and mask out enabled callbacks */ uint32_t flags = module->hw->INTFLAG.reg; if (flags & ADC_INTFLAG_RESRDY) { if ((module->enabled_callback_mask & (1 << ADC_CALLBACK_READ_BUFFER)) && (module->registered_callback_mask & (1 << ADC_CALLBACK_READ_BUFFER))) { /* clear interrupt flag */ module->hw->INTFLAG.reg = ADC_INTFLAG_RESRDY; while (adc_is_syncing(module)) { /* Wait for synchronization */ } /* store ADC result in job buffer */ *(module->job_buffer++) = module->hw->RESULT.reg; if (--module->remaining_conversions > 0) { if (module->software_trigger == true) { adc_start_conversion(module); } } else { if (module->job_status == STATUS_BUSY) { /* job is complete. update status,disable interrupt *and call callback */ module->job_status = STATUS_OK; adc_disable_interrupt(module, ADC_INTERRUPT_RESULT_READY); (module->callback[ADC_CALLBACK_READ_BUFFER])(module); } } } } if (flags & ADC_INTFLAG_WINMON) { module->hw->INTFLAG.reg = ADC_INTFLAG_WINMON; if ((module->enabled_callback_mask & (1 << ADC_CALLBACK_WINDOW)) && (module->registered_callback_mask & (1 << ADC_CALLBACK_WINDOW))) { (module->callback[ADC_CALLBACK_WINDOW])(module); } } if (flags & ADC_INTFLAG_OVERRUN) { module->hw->INTFLAG.reg = ADC_INTFLAG_OVERRUN; if ((module->enabled_callback_mask & (1 << ADC_CALLBACK_ERROR)) && (module->registered_callback_mask & (1 << ADC_CALLBACK_ERROR))) { (module->callback[ADC_CALLBACK_ERROR])(module); } } }
/** * \brief Aborts an ongoing job. * * Aborts an ongoing job. * * \param [in] module_inst Pointer to the ADC software instance struct * \param [in] type Type of job to abort */ void adc_abort_job( struct adc_module *module_inst, enum adc_job_type type) { /* Sanity check arguments */ Assert(module_inst); if (type == ADC_JOB_READ_BUFFER) { /* Disable interrupt */ adc_disable_interrupt(module_inst, ADC_INTERRUPT_RESULT_READY); /* Mark job as aborted */ module_inst->job_status = STATUS_ABORTED; module_inst->remaining_conversions = 0; } }
/** * \brief Callback function for ADCIFE interrupt. */ static void adcife_wm_handler(void) { uint32_t ul_mode; uint16_t us_adc; /* Disable Window Monitor Interrupt. */ adc_disable_interrupt(&g_adc_inst, ADC_WINDOW_MONITOR); if ((adc_get_status(&g_adc_inst) & ADCIFE_SR_WM) == ADCIFE_SR_WM) { ul_mode = adc_get_wm_mode(&g_adc_inst); us_adc = adc_get_last_conv_value(&g_adc_inst); switch (ul_mode) { case 1: printf("-ISR-:DAC output voltage %d mv is above the low threshold:%d mv!\n\r", (int)(us_adc * VOLT_REF / MAX_DIGITAL), (int)(gs_us_low_threshold * VOLT_REF / MAX_DIGITAL)); break; case 2: printf("-ISR-:DAC output voltage %d mv is below the high threshold:%d mv!\n\r", (int)(us_adc * VOLT_REF / MAX_DIGITAL), (int)(gs_us_high_threshold * VOLT_REF / MAX_DIGITAL)); break; case 3: printf("-ISR-:DAC output voltage %d mv is in the comparison window:%d-%d mv!\n\r", (int)(us_adc * VOLT_REF / MAX_DIGITAL), (int)(gs_us_low_threshold * VOLT_REF / MAX_DIGITAL), (int)(gs_us_high_threshold * VOLT_REF / MAX_DIGITAL)); break; case 4: printf("-ISR-:DAC output voltage %d mv is out of the comparison window:%d-%d mv!\n\r", (int)(us_adc * VOLT_REF / MAX_DIGITAL), (int)(gs_us_low_threshold * VOLT_REF / MAX_DIGITAL), (int)(gs_us_high_threshold * VOLT_REF / MAX_DIGITAL)); break; } adc_clear_status(&g_adc_inst, ADCIFE_SCR_WM); } }
void ADC_Handler(void) { uint32_t ul_mode; uint16_t us_adc; /* Disable Compare Interrupt. */ adc_disable_interrupt(ADC, ADC_IDR_COMPE); if ((adc_get_status(ADC) & ADC_ISR_COMPE) == ADC_ISR_COMPE) { ul_mode = adc_get_comparison_mode(ADC); us_adc = adc_get_channel_value(ADC, ADC_CHANNEL_POTENTIOMETER); switch (ul_mode) { case 0: printf("-ISR-:Potentiometer voltage %d mv is below the low " "threshold:%d mv!\n\r", us_adc * VOLT_REF / MAX_DIGITAL, gs_us_low_threshold * VOLT_REF / MAX_DIGITAL); break; case 1: printf("-ISR-:Potentiometer voltage %d mv is above the high " "threshold:%d mv!\n\r", us_adc * VOLT_REF / MAX_DIGITAL, gs_us_high_threshold * VOLT_REF / MAX_DIGITAL); break; case 2: printf("-ISR-:Potentiometer voltage %d mv is in the comparison " "window:%d-%d mv!\n\r", us_adc * VOLT_REF / MAX_DIGITAL, gs_us_low_threshold * VOLT_REF / MAX_DIGITAL, gs_us_high_threshold * VOLT_REF / MAX_DIGITAL); break; case 3: printf("-ISR-:Potentiometer voltage %d mv is out of the comparison" " window:%d-%d mv!\n\r", us_adc * VOLT_REF / MAX_DIGITAL, gs_us_low_threshold * VOLT_REF / MAX_DIGITAL, gs_us_high_threshold * VOLT_REF / MAX_DIGITAL); break; } } }
/** * \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); }
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(); }
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(); }
/** * \brief adc12 Application entry point. * * \return Unused (ANSI-C compatibility). */ int main(void) { uint32_t i; uint8_t uc_key; /* Initialize the SAM system. */ sysclk_init(); board_init(); configure_console(); /* Output example information. */ puts(STRING_HEADER); puts("Configure system tick to get 1ms tick period.\r"); if (SysTick_Config(sysclk_get_cpu_hz() / 1000)) { puts("-F- Systick configuration error\r"); while (1); } /* Set default ADC test mode. */ memset((void *)&g_adc_test_mode, 0, sizeof(g_adc_test_mode)); g_adc_test_mode.uc_trigger_mode = TRIGGER_MODE_SOFTWARE; g_adc_test_mode.uc_pdc_en = 1; g_adc_test_mode.uc_sequence_en = 0; g_adc_test_mode.uc_gain_en = 0; g_adc_test_mode.uc_offset_en = 0; display_menu(); start_adc(); puts("Press any key to display configuration menu.\r"); while (1) { /* ADC software trigger per 1s */ if (g_adc_test_mode.uc_trigger_mode == TRIGGER_MODE_SOFTWARE) { mdelay(1000); #if SAM3S || SAM3N || SAM3XA || SAM4S || SAM4C adc_start(ADC); #elif SAM3U #ifdef ADC_12B adc12b_start(ADC12B); #else adc_start(ADC); #endif #endif } /* Check if the user enters a key. */ if (!uart_read(CONSOLE_UART, &uc_key)) { #if SAM3S || SAM3N || SAM3XA || SAM4S || SAM4C adc_disable_interrupt(ADC, 0xFFFFFFFF); /* Disable all adc interrupt. */ #elif SAM3U #ifdef ADC_12B adc12b_disable_interrupt(ADC12B, 0xFFFFFFFF); /* Disable all adc interrupt. */ #else adc_disable_interrupt(ADC, 0xFFFFFFFF); /* Disable all adc interrupt. */ #endif #endif tc_start(TC0, 0); /* Stop the Timer. */ #if SAM3S || SAM3U || SAM3XA || SAM4S pwm_channel_disable(PWM, 0); #endif display_menu(); set_adc_test_mode(); start_adc(); puts("Press any key to display configuration menu.\r"); } /* Check if ADC sample is done. */ if (g_adc_sample_data.us_done == ADC_DONE_MASK) { for (i = 0; i < NUM_CHANNELS; i++) { printf("CH%02d: %04d mv. ", (int)g_adc_sample_data.uc_ch_num[i], (int)(g_adc_sample_data. us_value[i] * VOLT_REF / MAX_DIGITAL)); } puts("\r"); g_adc_sample_data.us_done = 0; } } }
/** * \brief Turn on/off ADC module. * * \param on True to start ADC, false to turn off. */ static void demo_start_adc(bool on) { uint32_t low_threshold, high_threshold; if (on == true) { /* Check if already enabled */ if (demo_adc_on) { return; } demo_config_adc(); /* Start TC0 and hardware trigger. */ tc_start(TC0, 1); /* Get the potentiometer initial value */ pontentiometer_value = adc_get_channel_value(ADC, ADC_CHANNEL_POTENTIOMETER); /* Set Window threshold according to the initial values */ low_threshold = pontentiometer_value - (NB_INTERVALS * (0x1000 / 256)); if (low_threshold > 0xf000000) { low_threshold = 0; } high_threshold = pontentiometer_value + (NB_INTERVALS * (0x1000 / 256)); if (high_threshold >= 0x1000) { high_threshold = 0x1000 - 1; } pontentiometer_value = pontentiometer_value*100 + 1; /* Channel 5 has to be compared. */ adc_set_comparison_channel(ADC, ADC_CHANNEL_POTENTIOMETER); /* Compare mode, out the window. */ adc_set_comparison_mode(ADC, ADC_EMR_CMPMODE_OUT); /* Set up Threshold. */ adc_set_comparison_window(ADC, low_threshold, high_threshold); /* Enable ADC interrupt. */ NVIC_EnableIRQ(ADC_IRQn); /* Enable Compare Interrupt. */ adc_enable_interrupt(ADC, ADC_IER_COMPE); /* Set adc on flag */ demo_adc_on = 1; /* Reset clapse time */ ppt_delay_clapse_counter = 0; } else { tc_stop(TC0, 1); /* Enable ADC interrupt. */ NVIC_DisableIRQ(ADC_IRQn); /* Enable Compare Interrupt. */ adc_disable_interrupt(ADC, ADC_IDR_COMPE); /* Set adc off flag */ demo_adc_on = 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"); } }