/** * \brief Measures and enables offset and gain corrections */ static void main_adc_correction(void) { /* ADC channel configuration structure */ struct adc_channel_config adcch_conf; uint16_t offset_correction; /* Expected value for gain correction at 1.9V * expected_value = Max. range * 1.9V / (VCC / 1.6) * Max. range = 12 bits signed = 11 bits unsigned */ const uint16_t expected_value = ((1 << 11) * 1900UL) / (3300L * 1000L / 1600L); /* Captured value for gain correction */ uint16_t captured_value; /* DAC Output 0 Volt */ main_dac_output(0); /* Capture value for 0 Volt */ adc_wait_for_interrupt_flag(&ADCA, ADC_CH0); adc_wait_for_interrupt_flag(&ADCA, ADC_CH0); offset_correction = adc_get_unsigned_result(&ADCA, ADC_CH0); /* Enable offset correction */ adcch_read_configuration(&ADCA, ADC_CH0, &adcch_conf); adcch_enable_correction(&adcch_conf, offset_correction, 1, 1); adcch_write_configuration(&ADCA, ADC_CH0, &adcch_conf); /* DAC Output 1.9 Volts */ main_dac_output(1900); /* Capture value for 1.9 Volts */ adc_wait_for_interrupt_flag(&ADCA, ADC_CH0); adc_wait_for_interrupt_flag(&ADCA, ADC_CH0); captured_value = adc_get_unsigned_result(&ADCA, ADC_CH0); /* Enable offset & gain correction */ adcch_enable_correction(&adcch_conf, offset_correction, expected_value, captured_value); adcch_write_configuration(&ADCA, ADC_CH0, &adcch_conf); printf("\n\rADC correction: "); printf("Offset correction %d, ", offset_correction); if (expected_value > captured_value) { printf("Gain correction 1.%03u\n\r\n\r", (uint16_t) ((((uint32_t)expected_value - captured_value) * 1000) / captured_value)); } else { printf("Gain correction 0.%03u\n\r\n\r", (uint16_t) (((uint32_t)expected_value * 1000) / captured_value)); } }
/** * \brief Measures and enables offset and gain corrections */ static void main_adc_correction_start(void) { /* ADC channel configuration structure */ struct adc_channel_config adcch_conf; static bool correction_measures_done = false; static uint16_t offset_correction; /* Expected value for gain correction at 1.9V * expected_value = Max. range (12 bits unsigned) * 1.9V / (VCC / 1.6) */ const uint16_t expected_value = ((1 << 12) * 1900UL) / (3300L * 1000L / 1600L); /* Captured value for gain correction */ static uint16_t captured_value; if (correction_measures_done) { goto main_adc_correction_enable; } printf("\n\r*Measure offset correction\n\r"); printf("Set PA0 pin to GND and press a key to trigge measurement.\n\r"); printf("Warning on STK600: Remove AREF0 jumper to do it.\n\r"); getchar(); /* Capture value for 0 Volt */ adc_start_conversion(&ADCA, ADC_CH0); adc_wait_for_interrupt_flag(&ADCA, ADC_CH0); offset_correction = adc_get_unsigned_result(&ADCA, ADC_CH0); /* Enable offset correction */ adcch_read_configuration(&ADCA, ADC_CH0, &adcch_conf); adcch_enable_correction(&adcch_conf, offset_correction, 1, 1); adcch_write_configuration(&ADCA, ADC_CH0, &adcch_conf); printf("*Measure Gain correction\n\r"); printf("Set PA0 pin to 1.9 Volt"); printf(" and press a key to trigge measurement.\r\n"); printf("Reminder on STK600: Set AREF0 jumper to do it.\n\r"); getchar(); /* Capture value for 1.9 Volts */ adc_start_conversion(&ADCA, ADC_CH0); adc_wait_for_interrupt_flag(&ADCA, ADC_CH0); captured_value = adc_get_unsigned_result(&ADCA, ADC_CH0); correction_measures_done = true; main_adc_correction_enable: /* Enable offset & gain correction */ adcch_read_configuration(&ADCA, ADC_CH0, &adcch_conf); adcch_enable_correction(&adcch_conf, offset_correction, expected_value, captured_value); adcch_write_configuration(&ADCA, ADC_CH0, &adcch_conf); printf("\n\r* ADC correction enabled: "); printf("Offset correction %d, ", offset_correction); if (expected_value > captured_value) { printf("Gain correction 1.%03u\n\r", (uint16_t) ((((uint32_t)expected_value - captured_value) * 1000) / captured_value)); } else { printf("Gain correction 0.%03u\n\r", (uint16_t) (((uint32_t)expected_value * 1000) / captured_value)); } }
/** * \internal * \brief Test correction conversion in 12-bit mode using the DAC * * These values are then measured using the ADC on the pins that are connected * to the DAC channel, and the results are compared and checked to see if they * are within the acceptable range of values that passes the test. * * \param test Current test case. */ static void run_correction_conversion_test( const struct test_case *test) { int16_t volt_output; int16_t volt_input; uint16_t error; /** Measures and enables offset and gain corrections */ /* ADC channel configuration structure */ struct adc_channel_config adcch_conf; uint16_t offset_correction; /* Expected value for gain correction at 1.9V * expected_value = Max. range * 1.9V / (VCC / 1.6) * Max. range = 12 bits signed = 11 bits unsigned */ const uint16_t expected_value = ((1 << 11) * 1900UL) / (3300L * 1000L / 1600L); /* Captured value for gain correction */ uint16_t captured_value; /* DAC Output 0 Volt */ main_dac_output(0); /* Capture value for 0 Volt */ adc_wait_for_interrupt_flag(&ADCA, ADC_CH0); adc_wait_for_interrupt_flag(&ADCA, ADC_CH0); offset_correction = adc_get_unsigned_result(&ADCA, ADC_CH0); /* Enable offset correction */ adcch_read_configuration(&ADCA, ADC_CH0, &adcch_conf); adcch_enable_correction(&adcch_conf, offset_correction, 1, 1); adcch_write_configuration(&ADCA, ADC_CH0, &adcch_conf); /* DAC Output 1.9 Volts */ main_dac_output(1900); /* Capture value for 1.9 Volts */ adc_wait_for_interrupt_flag(&ADCA, ADC_CH0); adc_wait_for_interrupt_flag(&ADCA, ADC_CH0); captured_value = adc_get_unsigned_result(&ADCA, ADC_CH0); /* Enable offset & gain correction */ adcch_enable_correction(&adcch_conf, offset_correction, expected_value, captured_value); adcch_write_configuration(&ADCA, ADC_CH0, &adcch_conf); /* Check values */ for (volt_output = -CONV_MAX_VOLTAGE; volt_output <= CONV_MAX_VOLTAGE; volt_output += CONV_VOLTAGE_STEP) { main_dac_output(volt_output); volt_input = main_adc_input(); if (volt_output > volt_input) { error = volt_output - volt_input; } else { error = volt_input - volt_output; } test_assert_true(test, error < CONF_TEST_ACCEPT_DELTA_CORRECTION, "ADC result is outside acceptable range (expected %d, captured %d)", volt_output, volt_input); } }