minimalist hardware testing support

Dependents:   MAX5715BOB_Tester MAX11131BOB_Tester MAX5171BOB_Tester MAX11410BOB_Tester ... more

MaximTinyTester.cpp

Committer:
whismanoid
Date:
2019-07-10
Revision:
3:080aa1bb1bc0
Parent:
2:9b20cadbfa15
Child:
5:67a1cd5a67cc

File content as of revision 3:080aa1bb1bc0:

// /*******************************************************************************
// * Copyright (C) 2019 Maxim Integrated Products, Inc., All Rights Reserved.
// *
// * Permission is hereby granted, free of charge, to any person obtaining a
// * copy of this software and associated documentation files (the "Software"),
// * to deal in the Software without restriction, including without limitation
// * the rights to use, copy, modify, merge, publish, distribute, sublicense,
// * and/or sell copies of the Software, and to permit persons to whom the
// * Software is furnished to do so, subject to the following conditions:
// *
// * The above copyright notice and this permission notice shall be included
// * in all copies or substantial portions of the Software.
// *
// * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
// * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// * OTHER DEALINGS IN THE SOFTWARE.
// *
// * Except as contained in this notice, the name of Maxim Integrated
// * Products, Inc. shall not be used except as stated in the Maxim Integrated
// * Products, Inc. Branding Policy.
// *
// * The mere transfer of this software does not imply any licenses
// * of trade secrets, proprietary technology, copyrights, patents,
// * trademarks, maskwork rights, or any other form of intellectual
// * property whatsoever. Maxim Integrated Products, Inc. retains all
// * ownership rights.
// *******************************************************************************
// */
// *********************************************************************
// @file MaximTinyTester.cpp
// *********************************************************************

#include "MaximTinyTester.h"

#ifndef LED_ON
# define LED_ON  0
#endif
#ifndef LED_OFF
# define LED_OFF 1
#endif

MaximTinyTester::MaximTinyTester(CmdLine& AssociatedCmdLine,
    AnalogIn& analogInPin0,
    AnalogIn& analogInPin1,
    AnalogIn& analogInPin2,
    AnalogIn& analogInPin3,
    AnalogIn& analogInPin4,
    AnalogIn& analogInPin5,
    DigitalOut& m_RFailLED,
    DigitalOut& m_GPassLED,
    DigitalOut& m_BBusyLED)
    : associatedCmdLine(AssociatedCmdLine)
    , analogInPin0(analogInPin0)
    , analogInPin1(analogInPin1)
    , analogInPin2(analogInPin2)
    , analogInPin3(analogInPin3)
    , analogInPin4(analogInPin4)
    , analogInPin5(analogInPin5)
    , m_RFailLED(m_RFailLED)
    , m_GPassLED(m_GPassLED)
    , m_BBusyLED(m_BBusyLED)
{
    nPass = 0;
    nFail = 0;
    err_threshold = 0.030; // 30mV
    input_timeout_time_msec = 250;
    settle_time_msec = 250;
    blink_time_msec = 75;
    analogInPin_fullScaleVoltage[0] = 3.300;
    analogInPin_fullScaleVoltage[1] = 3.300;
    analogInPin_fullScaleVoltage[2] = 3.300;
    analogInPin_fullScaleVoltage[3] = 3.300;
    analogInPin_fullScaleVoltage[4] = 3.300;
    analogInPin_fullScaleVoltage[5] = 3.300;
}

/** reset the pass/fail counters.
*
* @post nPass and nFail are reset to 0
*
*/
void MaximTinyTester::clear(void)
{
    nPass = 0;
    nFail = 0;
    // PinName NC means NOT_CONNECTED; DigitalOut::is_connected() returns false
    if (m_RFailLED.is_connected()) {
        m_RFailLED = LED_ON;
    }
    if (m_GPassLED.is_connected()) {
        m_GPassLED = LED_ON;
    }
    if (m_BBusyLED.is_connected()) {
        m_BBusyLED = LED_OFF;
    }
}

/** report that a test has completed with success.
*
* @post nPass is increased by 1
*
*/
void MaximTinyTester::PASS()
{
    ++nPass;
    // m_RFailLED = LED_ON; m_GPassLED = LED_ON; m_BBusyLED = LED_ON;
    // pulse blue LED during test to indicate activity
    if (m_GPassLED.is_connected()) {
        m_GPassLED = LED_OFF;
    }
    if (m_BBusyLED.is_connected()) {
        m_BBusyLED = LED_ON;
    }
    wait_ms(blink_time_msec); // delay
    if (m_GPassLED.is_connected()) {
        m_GPassLED = LED_ON;
    }
    if (m_BBusyLED.is_connected()) {
        m_BBusyLED = LED_OFF;
    }
    wait_ms(blink_time_msec); // delay
    associatedCmdLine.serial().printf("\r\n+PASS ");
}

/** report that a test has completed with failure.
*
* @post nFail is increased by 1
*
*/
void MaximTinyTester::FAIL()
{
    ++nFail;
    // m_RFailLED = LED_ON; m_GPassLED = LED_ON; m_BBusyLED = LED_ON;
    // pulse blue LED during test to indicate activity
    if (m_RFailLED.is_connected()) {
        m_RFailLED = LED_OFF;
    }
    if (m_BBusyLED.is_connected()) {
        m_BBusyLED = LED_ON;
    }
    wait_ms(blink_time_msec); // delay
    if (m_RFailLED.is_connected()) {
        m_RFailLED = LED_ON;
    }
    if (m_BBusyLED.is_connected()) {
        m_BBusyLED = LED_OFF;
    }
    wait_ms(blink_time_msec); // delay
    associatedCmdLine.serial().printf("\r\n-FAIL ");
#if USE_LEDS
    rgb_led.red(); // diagnostic rbg led RED
    //~ rgb_led.green(); // diagnostic rbg led GREEN
    //~ rgb_led.blue(); // diagnostic rbg led BLUE
    //~ rgb_led.white(); // diagnostic rbg led RED+GREEN+BLUE=WHITE
    //~ rgb_led.cyan(); // diagnostic rbg led GREEN+BLUE=CYAN
    //~ rgb_led.magenta(); // diagnostic rbg led RED+BLUE=MAGENTA
    //~ rgb_led.yellow(); // diagnostic rbg led RED+GREEN=YELLOW
    //~ rgb_led.black(); // diagnostic rbg led BLACK
#endif // USE_LEDS
}

/** Report number of pass and number of fail test results
*/
void MaximTinyTester::Report_Summary(void)
{
    associatedCmdLine.serial().printf("\r\nSummary: %d PASS %d FAIL\r\n", nPass, nFail);
    //~ associatedCmdLine.serial().printf(g_SelfTest_nPass);
    //~ associatedCmdLine.serial().printf(" PASS ");
    //~ associatedCmdLine.serial().printf(g_SelfTest_nFail);
    //~ associatedCmdLine.serial().printf(" FAIL\r\n");
    if (nFail == 0) {
        if (m_RFailLED.is_connected()) {
            m_RFailLED = LED_OFF;
        }
        if (m_GPassLED.is_connected()) {
            m_GPassLED = LED_ON;
        }
        if (m_BBusyLED.is_connected()) {
            m_BBusyLED = LED_OFF;
        }
        //~ rgb_led.green();     // diagnostic rbg led GREEN
    }
    else {
        if (m_RFailLED.is_connected()) {
            m_RFailLED = LED_ON;
        }
        if (m_GPassLED.is_connected()) {
            m_GPassLED = LED_OFF;
        }
        if (m_BBusyLED.is_connected()) {
            m_BBusyLED = LED_OFF;
        }
        //~ rgb_led.red(); // diagnostic rbg led RED
    }
}

/** Test a software function
*
* @param[in] nameOfFunctionUnderTest is the user-facing name of the function under test
*
* @param[in] functionUnderTest points to the function under test
*
* @param[in] voltageV is a test argument given to the function under test
*
* @param[in] expect_result contains the expected result
*
* @post nPass and nFail counters are updated
*
* @return true if success, false if test failed
*
*/
bool MaximTinyTester::FunctionCall_Expect(const char *nameOfFunctionUnderTest, 
    Callback<uint16_t(double)> functionUnderTest,
    double voltageV, uint16_t expect_result)
{
    uint16_t actual_result = functionUnderTest(voltageV);
    if (actual_result != expect_result)
    {
        FAIL();
        associatedCmdLine.serial().printf("%s(%6.4fV)", nameOfFunctionUnderTest, voltageV);
        associatedCmdLine.serial().printf(" expect %d", expect_result);
        associatedCmdLine.serial().printf(" but got %d", actual_result);
        return false;
    }
    else
    {
        PASS();
        associatedCmdLine.serial().printf("%s(%6.4fV)", nameOfFunctionUnderTest, voltageV);
        associatedCmdLine.serial().printf(" expect %d", expect_result);
        return true;
    }
    //~ associatedCmdLine.serial().printf("\r\n");
}

/** Test a software function
*
* @param[in] nameOfFunctionUnderTest is the user-facing name of the function under test
*
* @param[in] functionUnderTest points to the function under test
*
* @param[in] value_u16 is a test argument given to the function under test
*
* @param[in] expect_result contains the expected result
*
* @pre err_threshold determines how closely the result must match the expected value
*
* @post nPass and nFail counters are updated
*
* @return true if success, false if test failed
*
*/
bool MaximTinyTester::FunctionCall_Expect(const char *nameOfFunctionUnderTest, 
    Callback<double(uint16_t)> functionUnderTest,
    uint16_t value_u16, double expect_result)
{
    double actual_result = functionUnderTest(value_u16);
    double err_result = (actual_result - expect_result);
    if (( -err_threshold < err_result) && ( err_result < err_threshold))
    {
        PASS();
        associatedCmdLine.serial().printf("%s(%d)", nameOfFunctionUnderTest, value_u16);
        associatedCmdLine.serial().printf(" expect %6.6f", expect_result);
        return true;
    }
    else
    {
        FAIL();
        associatedCmdLine.serial().printf("%s(%d)", nameOfFunctionUnderTest, value_u16);
        associatedCmdLine.serial().printf(" expect %6.6f", expect_result);
        associatedCmdLine.serial().printf(" but got %6.6f", actual_result);
        associatedCmdLine.serial().printf(" err=%6.6f", err_result);
        return false;
    }
    //~ associatedCmdLine.serial().printf("\r\n");
}

/** Test an analog voltage input to the platform (output from the device under test)
*
* @param[in] expect_result contains the expected voltage
*
* @pre err_threshold determines how closely the result must match the expected value
*
* @post nPass and nFail counters are updated
*
* @return true if success, false if test failed
*
*/
bool MaximTinyTester::AnalogIn0_Read_Expect_voltageV(double expect_result)
{
    float adc_full_scale_voltage = analogInPin_fullScaleVoltage[0];
    // skip if expect_result exceeds ADC full scale
    if (adc_full_scale_voltage < expect_result)
    {
        // print a warning message that we can't perform the measurement
        associatedCmdLine.serial().printf("\r\n..... AIN full scale %1.3fV < expect %6.6f cannot perform measurement",
                                adc_full_scale_voltage, expect_result);
        return true; // ignore, test conditions are invalid; do not call PASS() or FAIL()
    }

    // TODO: tinyTester.Analog_Input_Expect_V replaces SelfTest_AnalogInput_Expect_ch_V
    // Platform board uses simple analog inputs
    float normValue_0_1 = analogInPin0.read();
    double actual_result = normValue_0_1 * adc_full_scale_voltage;
    double err_result = (actual_result - expect_result);
    if (( -err_threshold < err_result) && ( err_result < err_threshold))
    {
        PASS();
        //~ SelfTest_print_VoltageOfCode(cmdLine, value_u12);
        // Platform board uses simple analog inputs
        associatedCmdLine.serial().printf("AIN0 = %7.3f%% = %1.3fV  ",
                                normValue_0_1 * 100.0,
                                normValue_0_1 * adc_full_scale_voltage
                                );
        //
        associatedCmdLine.serial().printf(" expect %6.6f +/- %6.6f", expect_result, err_threshold);
        return true;
    }
    else
    {
        FAIL();
        //~ SelfTest_print_VoltageOfCode(cmdLine, value_u12);
        // Platform board uses simple analog inputs
        associatedCmdLine.serial().printf("AIN0 = %7.3f%% = %1.3fV  ",
                                normValue_0_1 * 100.0,
                                normValue_0_1 * adc_full_scale_voltage
                                );
        //
        associatedCmdLine.serial().printf(" expect %6.6f +/- %6.6f", expect_result, err_threshold);
        associatedCmdLine.serial().printf(" but got %6.6f", actual_result);
        associatedCmdLine.serial().printf(" err=%6.6f", err_result);
    }
    //~ associatedCmdLine.serial().printf("\r\n");
    return false;
}

/** Test an analog voltage input to the platform (output from the device under test)
*
* @param[in] expect_result contains the expected voltage
*
* @pre err_threshold determines how closely the result must match the expected value
*
* @post nPass and nFail counters are updated
*
* @return true if success, false if test failed
*
*/
bool MaximTinyTester::AnalogIn1_Read_Expect_voltageV(double expect_result)
{
    float adc_full_scale_voltage = analogInPin_fullScaleVoltage[1];
    // skip if expect_result exceeds ADC full scale
    if (adc_full_scale_voltage < expect_result)
    {
        // print a warning message that we can't perform the measurement
        associatedCmdLine.serial().printf("\r\n..... AIN full scale %1.3fV < expect %6.6f cannot perform measurement",
                                adc_full_scale_voltage, expect_result);
        return true; // ignore, test conditions are invalid; do not call PASS() or FAIL()
    }

    // TODO: tinyTester.Analog_Input_Expect_V replaces SelfTest_AnalogInput_Expect_ch_V
    // Platform board uses simple analog inputs
    float normValue_0_1 = analogInPin1.read();
    double actual_result = normValue_0_1 * adc_full_scale_voltage;
    double err_result = (actual_result - expect_result);
    if (( -err_threshold < err_result) && ( err_result < err_threshold))
    {
        PASS();
        //~ SelfTest_print_VoltageOfCode(cmdLine, value_u12);
        // Platform board uses simple analog inputs
        associatedCmdLine.serial().printf("AIN1 = %7.3f%% = %1.3fV  ",
                                normValue_0_1 * 100.0,
                                normValue_0_1 * adc_full_scale_voltage
                                );
        //
        associatedCmdLine.serial().printf(" expect %6.6f +/- %6.6f", expect_result, err_threshold);
        return true;
    }
    else
    {
        FAIL();
        //~ SelfTest_print_VoltageOfCode(cmdLine, value_u12);
        // Platform board uses simple analog inputs
        associatedCmdLine.serial().printf("AIN1 = %7.3f%% = %1.3fV  ",
                                normValue_0_1 * 100.0,
                                normValue_0_1 * adc_full_scale_voltage
                                );
        //
        associatedCmdLine.serial().printf(" expect %6.6f +/- %6.6f", expect_result, err_threshold);
        associatedCmdLine.serial().printf(" but got %6.6f", actual_result);
        associatedCmdLine.serial().printf(" err=%6.6f", err_result);
    }
    //~ associatedCmdLine.serial().printf("\r\n");
    return false;
}

/** Test an analog voltage input to the platform (output from the device under test)
*
* @param[in] expect_result contains the expected voltage
*
* @pre err_threshold determines how closely the result must match the expected value
*
* @post nPass and nFail counters are updated
*
* @return true if success, false if test failed
*
*/
bool MaximTinyTester::AnalogIn2_Read_Expect_voltageV(double expect_result)
{
    float adc_full_scale_voltage = analogInPin_fullScaleVoltage[2];
    // skip if expect_result exceeds ADC full scale
    if (adc_full_scale_voltage < expect_result)
    {
        // print a warning message that we can't perform the measurement
        associatedCmdLine.serial().printf("\r\n..... AIN full scale %1.3fV < expect %6.6f cannot perform measurement",
                                adc_full_scale_voltage, expect_result);
        return true; // ignore, test conditions are invalid; do not call PASS() or FAIL()
    }

    // TODO: tinyTester.Analog_Input_Expect_V replaces SelfTest_AnalogInput_Expect_ch_V
    // Platform board uses simple analog inputs
    float normValue_0_1 = analogInPin2.read();
    double actual_result = normValue_0_1 * adc_full_scale_voltage;
    double err_result = (actual_result - expect_result);
    if (( -err_threshold < err_result) && ( err_result < err_threshold))
    {
        PASS();
        //~ SelfTest_print_VoltageOfCode(cmdLine, value_u12);
        // Platform board uses simple analog inputs
        associatedCmdLine.serial().printf("AIN2 = %7.3f%% = %1.3fV  ",
                                normValue_0_1 * 100.0,
                                normValue_0_1 * adc_full_scale_voltage
                                );
        //
        associatedCmdLine.serial().printf(" expect %6.6f +/- %6.6f", expect_result, err_threshold);
        return true;
    }
    else
    {
        FAIL();
        //~ SelfTest_print_VoltageOfCode(cmdLine, value_u12);
        // Platform board uses simple analog inputs
        associatedCmdLine.serial().printf("AIN2 = %7.3f%% = %1.3fV  ",
                                normValue_0_1 * 100.0,
                                normValue_0_1 * adc_full_scale_voltage
                                );
        //
        associatedCmdLine.serial().printf(" expect %6.6f +/- %6.6f", expect_result, err_threshold);
        associatedCmdLine.serial().printf(" but got %6.6f", actual_result);
        associatedCmdLine.serial().printf(" err=%6.6f", err_result);
    }
    //~ associatedCmdLine.serial().printf("\r\n");
    return false;
}

/** Test an analog voltage input to the platform (output from the device under test)
*
* @param[in] expect_result contains the expected voltage
*
* @pre err_threshold determines how closely the result must match the expected value
*
* @post nPass and nFail counters are updated
*
* @return true if success, false if test failed
*
*/
bool MaximTinyTester::AnalogIn3_Read_Expect_voltageV(double expect_result)
{
    float adc_full_scale_voltage = analogInPin_fullScaleVoltage[3];
    // skip if expect_result exceeds ADC full scale
    if (adc_full_scale_voltage < expect_result)
    {
        // print a warning message that we can't perform the measurement
        associatedCmdLine.serial().printf("\r\n..... AIN full scale %1.3fV < expect %6.6f cannot perform measurement",
                                adc_full_scale_voltage, expect_result);
        return true; // ignore, test conditions are invalid; do not call PASS() or FAIL()
    }

    // TODO: tinyTester.Analog_Input_Expect_V replaces SelfTest_AnalogInput_Expect_ch_V
    // Platform board uses simple analog inputs
    float normValue_0_1 = analogInPin3.read();
    double actual_result = normValue_0_1 * adc_full_scale_voltage;
    double err_result = (actual_result - expect_result);
    if (( -err_threshold < err_result) && ( err_result < err_threshold))
    {
        PASS();
        //~ SelfTest_print_VoltageOfCode(cmdLine, value_u12);
        // Platform board uses simple analog inputs
        associatedCmdLine.serial().printf("AIN3 = %7.3f%% = %1.3fV  ",
                                normValue_0_1 * 100.0,
                                normValue_0_1 * adc_full_scale_voltage
                                );
        //
        associatedCmdLine.serial().printf(" expect %6.6f +/- %6.6f", expect_result, err_threshold);
        return true;
    }
    else
    {
        FAIL();
        //~ SelfTest_print_VoltageOfCode(cmdLine, value_u12);
        // Platform board uses simple analog inputs
        associatedCmdLine.serial().printf("AIN3 = %7.3f%% = %1.3fV  ",
                                normValue_0_1 * 100.0,
                                normValue_0_1 * adc_full_scale_voltage
                                );
        //
        associatedCmdLine.serial().printf(" expect %6.6f +/- %6.6f", expect_result, err_threshold);
        associatedCmdLine.serial().printf(" but got %6.6f", actual_result);
        associatedCmdLine.serial().printf(" err=%6.6f", err_result);
    }
    //~ associatedCmdLine.serial().printf("\r\n");
    return false;
}

/** Test an analog voltage input to the platform (output from the device under test)
*
* @param[in] expect_result contains the expected voltage
*
* @pre err_threshold determines how closely the result must match the expected value
*
* @post nPass and nFail counters are updated
*
* @return true if success, false if test failed
*
*/
bool MaximTinyTester::AnalogIn4_Read_Expect_voltageV(double expect_result)
{
    float adc_full_scale_voltage = analogInPin_fullScaleVoltage[4];
    // skip if expect_result exceeds ADC full scale
    if (adc_full_scale_voltage < expect_result)
    {
        // print a warning message that we can't perform the measurement
        associatedCmdLine.serial().printf("\r\n..... AIN full scale %1.3fV < expect %6.6f cannot perform measurement",
                                adc_full_scale_voltage, expect_result);
        return true; // ignore, test conditions are invalid; do not call PASS() or FAIL()
    }

    // TODO: tinyTester.Analog_Input_Expect_V replaces SelfTest_AnalogInput_Expect_ch_V
    // Platform board uses simple analog inputs
    float normValue_0_1 = analogInPin4.read();
    double actual_result = normValue_0_1 * adc_full_scale_voltage;
    double err_result = (actual_result - expect_result);
    if (( -err_threshold < err_result) && ( err_result < err_threshold))
    {
        PASS();
        //~ SelfTest_print_VoltageOfCode(cmdLine, value_u12);
        // Platform board uses simple analog inputs
        associatedCmdLine.serial().printf("AIN4 = %7.3f%% = %1.3fV  ",
                                normValue_0_1 * 100.0,
                                normValue_0_1 * adc_full_scale_voltage
                                );
        //
        associatedCmdLine.serial().printf(" expect %6.6f +/- %6.6f", expect_result, err_threshold);
        return true;
    }
    else
    {
        FAIL();
        //~ SelfTest_print_VoltageOfCode(cmdLine, value_u12);
        // Platform board uses simple analog inputs
        associatedCmdLine.serial().printf("AIN4 = %7.3f%% = %1.3fV  ",
                                normValue_0_1 * 100.0,
                                normValue_0_1 * adc_full_scale_voltage
                                );
        //
        associatedCmdLine.serial().printf(" expect %6.6f +/- %6.6f", expect_result, err_threshold);
        associatedCmdLine.serial().printf(" but got %6.6f", actual_result);
        associatedCmdLine.serial().printf(" err=%6.6f", err_result);
    }
    //~ associatedCmdLine.serial().printf("\r\n");
    return false;
}

/** Test an analog voltage input to the platform (output from the device under test)
*
* @param[in] expect_result contains the expected voltage
*
* @pre err_threshold determines how closely the result must match the expected value
*
* @post nPass and nFail counters are updated
*
* @return true if success, false if test failed
*
*/
bool MaximTinyTester::AnalogIn5_Read_Expect_voltageV(double expect_result)
{
    float adc_full_scale_voltage = analogInPin_fullScaleVoltage[5];
    // skip if expect_result exceeds ADC full scale
    if (adc_full_scale_voltage < expect_result)
    {
        // print a warning message that we can't perform the measurement
        associatedCmdLine.serial().printf("\r\n..... AIN full scale %1.3fV < expect %6.6f cannot perform measurement",
                                adc_full_scale_voltage, expect_result);
        return true; // ignore, test conditions are invalid; do not call PASS() or FAIL()
    }

    // TODO: tinyTester.Analog_Input_Expect_V replaces SelfTest_AnalogInput_Expect_ch_V
    // Platform board uses simple analog inputs
    float normValue_0_1 = analogInPin5.read();
    double actual_result = normValue_0_1 * adc_full_scale_voltage;
    double err_result = (actual_result - expect_result);
    if (( -err_threshold < err_result) && ( err_result < err_threshold))
    {
        PASS();
        //~ SelfTest_print_VoltageOfCode(cmdLine, value_u12);
        // Platform board uses simple analog inputs
        associatedCmdLine.serial().printf("AIN5 = %7.3f%% = %1.3fV  ",
                                normValue_0_1 * 100.0,
                                normValue_0_1 * adc_full_scale_voltage
                                );
        //
        associatedCmdLine.serial().printf(" expect %6.6f +/- %6.6f", expect_result, err_threshold);
        return true;
    }
    else
    {
        FAIL();
        //~ SelfTest_print_VoltageOfCode(cmdLine, value_u12);
        // Platform board uses simple analog inputs
        associatedCmdLine.serial().printf("AIN5 = %7.3f%% = %1.3fV  ",
                                normValue_0_1 * 100.0,
                                normValue_0_1 * adc_full_scale_voltage
                                );
        //
        associatedCmdLine.serial().printf(" expect %6.6f +/- %6.6f", expect_result, err_threshold);
        associatedCmdLine.serial().printf(" but got %6.6f", actual_result);
        associatedCmdLine.serial().printf(" err=%6.6f", err_result);
    }
    //~ associatedCmdLine.serial().printf("\r\n");
    return false;
}

bool MaximTinyTester::AnalogIn_Read_Expect_voltageV(AnalogIn& analogInPin, double expect_result)
{
    float adc_full_scale_voltage = analogInPin_fullScaleVoltage[0];
    // skip if expect_result exceeds ADC full scale
    if (adc_full_scale_voltage < expect_result)
    {
        // print a warning message that we can't perform the measurement
        associatedCmdLine.serial().printf("\r\n..... AIN full scale %1.3fV < expect %6.6f cannot perform measurement",
                                adc_full_scale_voltage, expect_result);
        return true; // ignore, test conditions are invalid; do not call PASS() or FAIL()
    }

    // TODO: tinyTester.Analog_Input_Expect_V replaces SelfTest_AnalogInput_Expect_ch_V
    // Platform board uses simple analog inputs
    float normValue_0_1 = analogInPin.read();
    double actual_result = normValue_0_1 * adc_full_scale_voltage;
    double err_result = (actual_result - expect_result);
    if (( -err_threshold < err_result) && ( err_result < err_threshold))
    {
        PASS();
        //~ SelfTest_print_VoltageOfCode(cmdLine, value_u12);
        // Platform board uses simple analog inputs
        associatedCmdLine.serial().printf("AIN0 = %7.3f%% = %1.3fV  ",
                                normValue_0_1 * 100.0,
                                normValue_0_1 * adc_full_scale_voltage
                                );
        //
        associatedCmdLine.serial().printf(" expect %6.6f +/- %6.6f", expect_result, err_threshold);
        return true;
    }
    else
    {
        FAIL();
        //~ SelfTest_print_VoltageOfCode(cmdLine, value_u12);
        // Platform board uses simple analog inputs
        associatedCmdLine.serial().printf("AIN0 = %7.3f%% = %1.3fV  ",
                                normValue_0_1 * 100.0,
                                normValue_0_1 * adc_full_scale_voltage
                                );
        //
        associatedCmdLine.serial().printf(" expect %6.6f +/- %6.6f", expect_result, err_threshold);
        associatedCmdLine.serial().printf(" but got %6.6f", actual_result);
        associatedCmdLine.serial().printf(" err=%6.6f", err_result);
    }
    //~ associatedCmdLine.serial().printf("\r\n");
    return false;
}

bool MaximTinyTester::DigitalIn_Read_Expect_WarnOnly(DigitalIn& digitalInPin, const char* pinName, int expect_result, const char *expect_description)
{
    int actual_UPO_value = -1;
    for (int retry_count = 0; retry_count < 10; retry_count++) {
        actual_UPO_value = digitalInPin.read(); // g_MAX5171_device.UPOinputValue();
        if (actual_UPO_value == expect_result) {
            PASS();
            associatedCmdLine.serial().printf("%s signal=%d %s", pinName, expect_result, expect_description);
            return true;
        }
        // UPO condition not met, retry for a while until give up
        wait_ms(input_timeout_time_msec / 10); // delay
    }
    associatedCmdLine.serial().printf("\r\n!WARN "); // SelfTest_FAIL(cmdLine);
    associatedCmdLine.serial().printf("expected %s signal=%d %s", pinName, expect_result, expect_description);
    associatedCmdLine.serial().printf(", but got actual %s=%d", pinName, actual_UPO_value);
    associatedCmdLine.serial().printf(", missing %s connections?", pinName);
    return false;
}

void MaximTinyTester::Wait_Output_Settling()
{
    wait_ms(settle_time_msec); // delay
}


// End of file