/** * \brief Handler for ADC interrupt. */ void ADC_Handler(void) { uint32_t low_threshold; uint32_t high_threshold; uint32_t status = adc_get_status(ADC); /* Read the status to ack the IT */ if ((status & ADC_ISR_COMPE) == ADC_ISR_COMPE) { /* 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 > 0xf0000000) { low_threshold = 0; } high_threshold = pontentiometer_value + (NB_INTERVALS * (0x1000 / 256)); if (high_threshold >= 0x1000) { high_threshold = 0x1000 - 1; } /* Normalize the value 0 -> 255 */ pontentiometer_value = pontentiometer_value*100 + 1; ppt_delay_clapse_counter = 0; /* Setup Threshold*/ adc_set_comparison_window( ADC, low_threshold, high_threshold); /* Compare mode, in the window. */ adc_enable_interrupt(ADC, ADC_IER_COMPE); } if (status & ADC_ISR_ENDRX) { /* Start next buffer */ ADC->ADC_RNPR = (uint32_t) frame_buffer[(adc_buf_ndx + 2) % AUDIO_NB_BUFFER]; ADC->ADC_RNCR = AUDIO_FRAME_SIZE; adc_buf_ndx = (adc_buf_ndx + 1) % AUDIO_NB_BUFFER; adc_nb_samples += AUDIO_FRAME_SIZE; } }
/** * \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 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; } }