/** * \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 Executes several ADC captures according to several DAC output * This functions send a table with all conversions on STDIO output. * * \param values Values from ADC */ static void main_conversions(uint16_t values[]) { int16_t volt_output; for (volt_output = -CONV_MAX_VOLTAGE; volt_output <= CONV_MAX_VOLTAGE; volt_output += CONV_VOLTAGE_STEP) { main_dac_output(volt_output); *values++ = main_adc_input(); } }
/** * \internal * \brief Test averaging 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 average of values that passes the test. * * \param test Current test case. */ static void run_averaging_conversion_test( const struct test_case *test) { int16_t volt_output; int16_t volt_min, volt_max, volt_input; /* ADC module configuration structure */ struct adc_config adc_conf; /* ADC channel configuration structure */ struct adc_channel_config adcch_conf; adc_disable(&ADCA); /* Change resolution parameter to accept averaging */ adc_read_configuration(&ADCA, &adc_conf); adc_set_conversion_parameters(&adc_conf, ADC_SIGN_ON, ADC_RES_MT12, ADC_REF_VCC); adc_write_configuration(&ADCA, &adc_conf); /* Enable averaging */ adcch_read_configuration(&ADCA, ADC_CH0, &adcch_conf); adcch_enable_averaging(&adcch_conf, ADC_SAMPNUM_1024X); adcch_write_configuration(&ADCA, ADC_CH0, &adcch_conf); adc_enable(&ADCA); adc_wait_for_interrupt_flag(&ADCA, ADC_CH0); /* Check values */ for (volt_output = -CONV_MAX_VOLTAGE; volt_output <= CONV_MAX_VOLTAGE; volt_output += CONV_VOLTAGE_STEP) { main_dac_output(volt_output); /* first capture */ volt_input = main_adc_input(); volt_min = volt_max = volt_input; /* several capture */ for (uint8_t i = 0; i < 5; i++) { volt_input = main_adc_input(); if (volt_min > volt_input) { volt_min = volt_input; } if (volt_max < volt_input) { volt_max = volt_input; } } test_assert_true(test, (volt_max - volt_min) < CONF_TEST_ACCEPT_DELTA_AVERAGING, "ADC result is not in acceptable stable range (Min %dmV, Max %dmV)", volt_min, volt_max); } }
/** * \brief Executes several ADC captures according to several DAC output * This functions send a table with all conversions on STDIO output. */ static void main_conversions(void) { int16_t volt_output, volt_input; printf("| ADC input | ADC res. | Delta |\n\r"); for (volt_output = -1800; volt_output <= 1800; volt_output += 600) { main_dac_output(volt_output); volt_input = main_adc_input(); printf("| %5d mV | %5d mV | %4d mV |\n\r", volt_output, volt_input, volt_input - volt_output); } }
/** * \internal * \brief Test standard 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_standard_conversion_test( const struct test_case *test) { int16_t volt_output; int16_t volt_input; uint16_t error; 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, "ADC result is outside acceptable range (expected %d, captured %d)", volt_output, volt_input); } }
/** * \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); } }