Test program running on MAX32625MBED. Control through USB Serial commands using a terminal emulator such as teraterm or putty.

Dependencies:   MaximTinyTester CmdLine MAX5171 USBDevice

Revision:
0:3edb3708c8c5
Child:
1:40369075c365
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Jun 10 07:53:42 2019 +0000
@@ -0,0 +1,7951 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************
+ */
+
+#include "mbed.h"
+#include "USBSerial.h"
+
+#include "CmdLine.h"
+#include "MaximTinyTester.h"
+
+#include "MAX5715.h"
+
+// TODO: trim cruft
+
+
+
+//----------------------------------------------------------------------
+// mbed-os compatability tests...
+//----------------------------------------------------------------------
+// mbed-os-5.12: buildable; warnings
+//
+// Not supported by MAX32625MBED... better stick with mbed-os-5.11 for now.
+// Watch out for conflict with USBDevice library.
+// Now that USBSerial is part of the official mbed-os-5.12 API,
+// remove the external USBDevice library if present:
+//    mbed remove USBDevice
+//
+//    cd mbed-os ; mbed update mbed-os-5.12 ; cd ..; mbed remove USBDevice
+//----------------------------------------------------------------------
+// mbed-os-5.11: buildable; warnings
+//
+// fixed: format '%d' expects argument of type 'int', but argument _ has type 'uint32_t {aka long unsigned int}' [-Wformat=]
+// fixed: 'static osStatus rtos::Thread::wait(uint32_t)' is deprecated: Static methods only affecting current thread cause confusion. Replaced by ThisThread::sleep_for. [since mbed-os-5.10] [-Wdeprecated-declarations]
+//
+// prior to mbed-os-5.12, USBSerial required an external library:
+//    mbed add https://developer.mbed.org/teams/MaximIntegrated/code/USBDevice/
+//
+//    cd mbed-os ; mbed update mbed-os-5.11
+//    cd .. ; mbed sync
+//----------------------------------------------------------------------
+// mbed-os-5.10 buildable; warning about wait function
+// 'static osStatus rtos::Thread::wait(uint32_t)' is deprecated: Static methods only affecting current thread cause confusion. Replaced by ThisThread::sleep_for. [since mbed-os-5.10] [-Wdeprecated-declarations]
+//
+// prior to mbed-os-5.12, USBSerial required an external library:
+//    mbed add https://developer.mbed.org/teams/MaximIntegrated/code/USBDevice/
+//
+//    cd mbed-os ; mbed update mbed-os-5.10
+//    cd .. ; mbed sync
+//----------------------------------------------------------------------
+// mbed-os-5.9 buildable
+//
+// prior to mbed-os-5.12, USBSerial required an external library:
+//    mbed add https://developer.mbed.org/teams/MaximIntegrated/code/USBDevice/
+//
+//    cd mbed-os ; mbed update mbed-os-5.9
+//    cd .. ; mbed sync
+//----------------------------------------------------------------------
+// mbed-os-5.8 buildable
+//
+// prior to mbed-os-5.12, USBSerial required an external library:
+//    mbed add https://developer.mbed.org/teams/MaximIntegrated/code/USBDevice/
+//
+//    cd mbed-os ; mbed update mbed-os-5.8
+//    cd .. ; mbed sync
+//---------------------------------------------------------------------
+// mbed-os-5.7 buildable
+//
+// prior to mbed-os-5.12, USBSerial required an external library:
+//    mbed add https://developer.mbed.org/teams/MaximIntegrated/code/USBDevice/
+//
+//    cd mbed-os ; mbed update mbed-os-5.7
+//    cd .. ; mbed sync
+//----------------------------------------------------------------------
+// mbed-os-5.6 pass
+// [Warning] USBSerial.h@59,203: 'mbed::FunctionPointerArg1<R, void>::FunctionPointerArg1(R (*)()) [with R = void]' is deprecated: FunctionPointer has been replaced by Callback<void()> [since mbed-os-5.1] [-Wdeprecated-declarations]
+// [Warning] USBSerial.h@134,27: 'void mbed::Callback<R()>::attach(R (*)()) [with R = void]' is deprecated: Replaced by simple assignment 'Callback cb = func [since mbed-os-5.4] [-Wdeprecated-declarations]
+//
+// prior to mbed-os-5.12, USBSerial required an external library:
+//    mbed add https://developer.mbed.org/teams/MaximIntegrated/code/USBDevice/
+//
+//    cd mbed-os ; mbed update mbed-os-5.6
+//    cd .. ; mbed sync
+//----------------------------------------------------------------------
+
+// Test fixture and application menu for breakout boards:
+//   - MAX5715BOB
+//   - MAX11131BOB
+//   - MAX5171BOB
+// Platforms:
+//   - MAX32625MBED
+//   - NUCLEO_F446RE
+//   - NUCLEO_F401RE
+
+#include "mbed.h"
+#if defined(TARGET)
+// TARGET_NAME macros from targets/TARGET_Maxim/TARGET_MAX32625/device/mxc_device.h
+// Create a string definition for the TARGET
+#define STRING_ARG(arg) #arg
+#define STRING_NAME(name) STRING_ARG(name)
+#define TARGET_NAME STRING_NAME(TARGET)
+#elif defined(TARGET_LPC1768)
+#define TARGET_NAME "LPC1768"
+#elif defined(TARGET_NUCLEO_F446RE)
+#define TARGET_NAME "NUCLEO_F446RE"
+#elif defined(TARGET_NUCLEO_F401RE)
+#define TARGET_NAME "NUCLEO_F401RE"
+#else
+#error TARGET NOT DEFINED
+#endif
+#if defined(TARGET_MAX32630)
+//--------------------------------------------------
+// TARGET=MAX32630FTHR ARM Cortex-M4F 96MHz 2048kB Flash 512kB SRAM
+//             +-------------[microUSB]-------------+
+//             | J1         MAX32630FTHR        J2  |
+//      ______ | [ ] RST                    GND [ ] |
+//      ______ | [ ] 3V3                    BAT+[ ] |
+//      ______ | [ ] 1V8                  reset SW1 |
+//      ______ | [ ] GND       J4               J3  |
+// analogIn0/4 | [a] AIN_0 1.2Vfs     (bat) SYS [ ] | switched BAT+
+// analogIn1/5 | [a] AIN_1 1.2Vfs           PWR [ ] | external pwr btn
+// analogIn2   | [a] AIN_2 1.2Vfs      +5V VBUS [ ] | USB +5V power
+// analogIn3   | [a] AIN_3 1.2Vfs   1-WIRE P4_0 [d] | dig9
+//  (I2C2.SDA) | [d] P5_7  SDA2        SRN P5_6 [d] | dig8
+//  (I2C2.SCL) | [d] P6_0  SCL2      SDIO3 P5_5 [d] | dig7
+//  (SPI.SCLK) | [s] P5_0  SCLK      SDIO2 P5_4 [d] | dig6
+//  (SPI.MOSI) | [s] P5_1  MOSI       SSEL P5_3 [d] | dig5
+//  (SPI.MISO) | [s] P5_2  MISO        RTS P3_3 [d] | dig4
+//  (SPI.CS  ) | [s] P3_0  RX          CTS P3_2 [d] | dig3
+//        dig0 | [d] P3_1  TX          SCL P3_5 [d] | dig2
+//      ______ | [ ] GND               SDA P3_4 [d] | dig1
+//             |                                    |
+//             | XIP Flash      MAX14690N           |
+//             | XIP_SCLK P1_0  SDA2 P5_7           |
+//             | XIP_MOSI P1_1  SCL2 P6_0           |
+//             | XIP_MISO P1_2  PMIC_INIT P3_7      |
+//             | XIP_SSEL P1_3  MPC P2_7            |
+//             | XIP_DIO2 P1_4  MON AIN_0           |
+//             | XIP_DIO3 P1_5                      |
+//             |                                    |
+//             | PAN1326B     MicroSD        LED    |
+//             | BT_RX  P0_0  SD_SCLK P0_4   r P2_4 |
+//             | BT_TX  P0_1  SD_MOSI P0_5   g P2_5 |
+//             | BT_CTS P0_2  SD_MISO P0_6   b P2_6 |
+//             | BT_RTS P0_3  SD_SSEL P0_7          |
+//             | BT_RST P1_6  DETECT  P2_2          |
+//             | BT_CLK P1_7               SW2 P2_3 |
+//             +------------------------------------+
+// MAX32630FTHR board has MAX14690 PMIC on I2C bus (P5_7 SDA, P6_0 SCL) at slave address 0101_000r 0x50 (or 0x28 for 7 MSbit address).
+// MAX32630FTHR board has BMI160 accelerometer on I2C bus (P5_7 SDA, P6_0 SCL) at slave address 1101_000r 0xD0 (or 0x68 for 7 MSbit address).
+// AIN_0 = AIN0 pin       fullscale is 1.2V
+// AIN_1 = AIN1 pin       fullscale is 1.2V
+// AIN_2 = AIN2 pin       fullscale is 1.2V
+// AIN_3 = AIN3 pin       fullscale is 1.2V
+// AIN_4 = AIN0 / 5.0     fullscale is 6.0V
+// AIN_5 = AIN1 / 5.0     fullscale is 6.0V
+// AIN_6 = VDDB / 4.0     fullscale is 4.8V
+// AIN_7 = VDD18          fullscale is 1.2V
+// AIN_8 = VDD12          fullscale is 1.2V
+// AIN_9 = VRTC / 2.0     fullscale is 2.4V
+// AIN_10 = x undefined?
+// AIN_11 = VDDIO / 4.0   fullscale is 4.8V
+// AIN_12 = VDDIOH / 4.0  fullscale is 4.8V
+//
+    #include "max32630fthr.h"
+MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3);
+#define analogIn4_IS_HIGH_RANGE_OF_analogIn0 1
+// MAX32630FTHR board supports only internal VREF = 1.200V at bypass capacitor C15
+const float ADC_FULL_SCALE_VOLTAGE = 1.200;
+//--------------------------------------------------
+#elif defined(TARGET_MAX32625MBED)
+//--------------------------------------------------
+// TARGET=MAX32625MBED ARM Cortex-M4F 96MHz 512kB Flash 160kB SRAM
+//             +-------------------------------------+
+//             |   MAX32625MBED Arduino UNO header   |
+//             |                                     |
+//             |                           A5/SCL[ ] |   P1_7 dig15
+//             |                           A4/SDA[ ] |   P1_6 dig14
+//             |                         AREF=N/C[ ] |
+//             |                              GND[ ] |
+//             | [ ]N/C                    SCK/13[ ] |   P1_0 dig13
+//             | [ ]IOREF=3V3             MISO/12[ ] |   P1_2 dig12
+//             | [ ]RST                   MOSI/11[ ]~|   P1_1 dig11
+//             | [ ]3V3                     CS/10[ ]~|   P1_3 dig10
+//             | [ ]5V0                         9[ ]~|   P1_5 dig9
+//             | [ ]GND                         8[ ] |   P1_4 dig8
+//             | [ ]GND                              |
+//             | [ ]Vin                         7[ ] |   P0_7 dig7
+//             |                                6[ ]~|   P0_6 dig6
+//       AIN_0 | [ ]A0                          5[ ]~|   P0_5 dig5
+//       AIN_1 | [ ]A1                          4[ ] |   P0_4 dig4
+//       AIN_2 | [ ]A2                     INT1/3[ ]~|   P0_3 dig3
+//       AIN_3 | [ ]A3                     INT0/2[ ] |   P0_2 dig2
+// dig16  P3_4 | [ ]A4/SDA  RST SCK MISO     TX>1[ ] |   P0_1 dig1
+// dig17  P3_5 | [ ]A5/SCL  [ ] [ ] [ ]      RX<0[ ] |   P0_0 dig0
+//             |            [ ] [ ] [ ]              |
+//             |  UNO_R3    GND MOSI 5V  ____________/
+//              \_______________________/
+//
+//             +------------------------+
+//             |                        |
+//             |  MicroSD        LED    |
+//             |  SD_SCLK P2_4   r P3_0 |
+//             |  SD_MOSI P2_5   g P3_1 |
+//             |  SD_MISO P2_6   b P3_2 |
+//             |  SD_SSEL P2_7   y P3_3 |
+//             |                        |
+//             |  DAPLINK      BUTTONS  |
+//             |  TX P2_1      SW3 P2_3 |
+//             |  RX P2_0      SW2 P2_2 |
+//             +------------------------+
+//
+// AIN_0 = AIN0 pin       fullscale is 1.2V
+// AIN_1 = AIN1 pin       fullscale is 1.2V
+// AIN_2 = AIN2 pin       fullscale is 1.2V
+// AIN_3 = AIN3 pin       fullscale is 1.2V
+// AIN_4 = AIN0 / 5.0     fullscale is 6.0V
+// AIN_5 = AIN1 / 5.0     fullscale is 6.0V
+// AIN_6 = VDDB / 4.0     fullscale is 4.8V
+// AIN_7 = VDD18          fullscale is 1.2V
+// AIN_8 = VDD12          fullscale is 1.2V
+// AIN_9 = VRTC / 2.0     fullscale is 2.4V
+// AIN_10 = x undefined?
+// AIN_11 = VDDIO / 4.0   fullscale is 4.8V
+// AIN_12 = VDDIOH / 4.0  fullscale is 4.8V
+//
+//#include "max32625mbed.h" // ?
+//MAX32625MBED mbed(MAX32625MBED::VIO_3V3); // ?
+#define analogIn4_IS_HIGH_RANGE_OF_analogIn0 1
+// MAX32630FTHR board supports only internal VREF = 1.200V at bypass capacitor C15
+const float ADC_FULL_SCALE_VOLTAGE = 1.200;     // TODO: ADC_FULL_SCALE_VOLTAGE Pico?
+// Arduino connector
+#ifndef A0
+#define A0 AIN_0
+#endif
+#ifndef A1
+#define A1 AIN_1
+#endif
+#ifndef A2
+#define A2 AIN_2
+#endif
+#ifndef A3
+#define A3 AIN_3
+#endif
+#ifndef D0
+#define D0 P0_0
+#endif
+#ifndef D1
+#define D1 P0_1
+#endif
+#ifndef D2
+#define D2 P0_2
+#endif
+#ifndef D3
+#define D3 P0_3
+#endif
+#ifndef D4
+#define D4 P0_4
+#endif
+#ifndef D5
+#define D5 P0_5
+#endif
+#ifndef D6
+#define D6 P0_6
+#endif
+#ifndef D7
+#define D7 P0_7
+#endif
+#ifndef D8
+#define D8 P1_4
+#endif
+#ifndef D9
+#define D9 P1_5
+#endif
+#ifndef D10
+#define D10 P1_3
+#endif
+#ifndef D11
+#define D11 P1_1
+#endif
+#ifndef D12
+#define D12 P1_2
+#endif
+#ifndef D13
+#define D13 P1_0
+#endif
+//--------------------------------------------------
+#elif defined(TARGET_NUCLEO_F446RE) || defined(TARGET_NUCLEO_F401RE)
+// TODO1: target NUCLEO_F446RE
+//
+// USER_BUTTON PC13
+// LED1 is shared with SPI_SCK on NUCLEO_F446RE PA_5, so don't use LED1.
+#define USE_LEDS 0
+// SPI spi(SPI_MOSI, SPI_MISO, SPI_SCK);
+// Serial microUSBserial(SERIAL_TX, SERIAL_RX);
+#define analogIn4_IS_HIGH_RANGE_OF_analogIn0 0
+const float ADC_FULL_SCALE_VOLTAGE = 3.300;     // TODO: ADC_FULL_SCALE_VOLTAGE Pico?
+//
+//--------------------------------------------------
+#elif defined(TARGET_LPC1768)
+//--------------------------------------------------
+// TARGET=LPC1768 ARM Cortex-M3 100 MHz 512kB flash 64kB SRAM
+//               +-------------[microUSB]-------------+
+//        ______ | [ ] GND             +3.3V VOUT [ ] | ______
+//        ______ | [ ] 4.5V<VIN<9.0V   +5.0V VU   [ ] | ______
+//        ______ | [ ] VB                 USB.IF- [ ] | ______
+//        ______ | [ ] nR                 USB.IF+ [ ] | ______
+// digitalInOut0 | [ ] p5 MOSI       ETHERNET.RD- [ ] | ______
+// digitalInOut1 | [ ] p6 MISO       ETHERNET.RD+ [ ] | ______
+// digitalInOut2 | [ ] p7 SCLK       ETHERNET.TD- [ ] | ______
+// digitalInOut3 | [ ] p8            ETHERNET.TD+ [ ] | ______
+// digitalInOut4 | [ ] p9  TX SDA          USB.D- [ ] | ______
+// digitalInOut5 | [ ] p10 RX SCL          USB.D+ [ ] | ______
+// digitalInOut6 | [ ] p11    MOSI     CAN-RD p30 [ ] | digitalInOut13
+// digitalInOut7 | [ ] p12    MISO     CAN-TD p29 [ ] | digitalInOut12
+// digitalInOut8 | [ ] p13 TX SCLK     SDA TX p28 [ ] | digitalInOut11
+// digitalInOut9 | [ ] p14 RX          SCL RX p27 [ ] | digitalInOut10
+//     analogIn0 | [ ] p15 AIN0 3.3Vfs   PWM1 p26 [ ] | pwmDriver1
+//     analogIn1 | [ ] p16 AIN1 3.3Vfs   PWM2 p25 [ ] | pwmDriver2
+//     analogIn2 | [ ] p17 AIN2 3.3Vfs   PWM3 p24 [ ] | pwmDriver3
+//     analogIn3 | [ ] p18 AIN3 AOUT     PWM4 p23 [ ] | pwmDriver4
+//     analogIn4 | [ ] p19 AIN4 3.3Vfs   PWM5 p22 [ ] | pwmDriver5
+//     analogIn5 | [ ] p20 AIN5 3.3Vfs   PWM6 p21 [ ] | pwmDriver6
+//               +------------------------------------+
+// AIN6 = P0.3 = TGT_SBL_RXD?
+// AIN7 = P0.2 = TGT_SBL_TXD?
+//
+//--------------------------------------------------
+// LPC1768 board uses VREF = 3.300V +A3,3V thru L1 to bypass capacitor C14
+#define analogIn4_IS_HIGH_RANGE_OF_analogIn0 0
+const float ADC_FULL_SCALE_VOLTAGE = 3.300;
+#else // not defined(TARGET_LPC1768 etc.)
+//--------------------------------------------------
+// unknown target
+//--------------------------------------------------
+#endif // target definition
+
+
+//--------------------------------------------------
+// alphanumeric command codes A-Z,a-z,0-9 reserved for application use
+#ifndef APPLICATION_ArduinoPinsMonitor
+#define APPLICATION_ArduinoPinsMonitor 1
+#endif // APPLICATION_ArduinoPinsMonitor
+
+//--------------------------------------------------
+// Support MAX5715BOB Breakout Board
+#ifndef APPLICATION_MAX5715
+#define APPLICATION_MAX5715 1
+#endif // APPLICATION_MAX5715
+#if APPLICATION_MAX5715 // header file
+#include "MAX5715.h"
+// suppress the I2C diagnostics, not relevant to this chip
+#define HAS_I2C 0
+#endif // APPLICATION_MAX5715
+
+//--------------------------------------------------
+// Support MAX11131BOB Breakout Board
+#ifndef APPLICATION_MAX11131
+#define APPLICATION_MAX11131 0
+#endif // APPLICATION_MAX11131
+#if APPLICATION_MAX11131 // header file
+#include "MAX11131.h"
+// suppress the I2C diagnostics, not relevant to this chip
+#define HAS_I2C 0
+#endif // APPLICATION_MAX11131
+
+//--------------------------------------------------
+// Support MAX5171BOB Breakout Board
+#ifndef APPLICATION_MAX5171
+#define APPLICATION_MAX5171 0
+#endif // APPLICATION_MAX5171
+#if APPLICATION_MAX5171 // header file
+#include "MAX5171.h"
+// suppress the I2C diagnostics, not relevant to this chip
+#define HAS_I2C 0
+#endif // APPLICATION_MAX5171
+
+//--------------------------------------------------
+// Support MAX11410BOB Breakout Board (placeholder)
+#ifndef APPLICATION_MAX11410
+#define APPLICATION_MAX11410 0
+#endif // APPLICATION_MAX11410
+#if APPLICATION_MAX11410 // header file
+#include "MAX11410.h"
+#endif // APPLICATION_MAX11410
+
+//--------------------------------------------------
+// Support MAX12345BOB Breakout Board (placeholder)
+#ifndef APPLICATION_MAX12345
+#define APPLICATION_MAX12345 0
+#endif // APPLICATION_MAX12345
+#if APPLICATION_MAX12345 // header file
+#include "MAX12345.h"
+#endif // APPLICATION_MAX12345
+
+
+#include "MAX541.h"
+
+#ifndef USE_MAXIMTINYTESTER
+#define USE_MAXIMTINYTESTER 1
+#endif // USE_MAXIMTINYTESTER
+#if USE_MAXIMTINYTESTER
+#include "MaximTinyTester.h"
+#endif // USE_MAXIMTINYTESTER
+#if USE_MAXIMTINYTESTER
+#else // USE_MAXIMTINYTESTER
+#endif // USE_MAXIMTINYTESTER
+
+//--------------------------------------------------
+// Option to dedicate SPI port pins
+//
+//    SPI2_MOSI  = P5_1
+//    SPI2_MISO  = P5_2
+//    SPI2_SCK   = P5_0
+//    On this board I'm using P3_0 as spi_cs
+//    SPI2_SS    = P5_3
+//    SPI2_SDIO2 = P5_4
+//    SPI2_SDIO3 = P5_5
+//    SPI2_SRN   = P5_6
+//
+#ifndef HAS_SPI
+#define HAS_SPI 1
+#endif
+#if HAS_SPI
+#define SPI_MODE0 0
+#define SPI_MODE1 1
+#define SPI_MODE2 2
+#define SPI_MODE3 3
+//
+// Define application-specific default SPI_SCLK_Hz and SPI_dataMode
+#if APPLICATION_MAX5715 // SPI interface default settings
+//
+//#define SPI_SCLK_Hz 48000000 // 48MHz
+//#define SPI_SCLK_Hz 24000000 // 24MHz
+#define SPI_SCLK_Hz 12000000 // 12MHz
+//#define SPI_SCLK_Hz 4000000 // 4MHz
+//#define SPI_SCLK_Hz 2000000 // 2MHz
+//#define SPI_SCLK_Hz 1000000 // 1MHz
+#define SPI_dataMode SPI_MODE2 // CPOL=1,CPHA=0: Falling Edge stable; SCLK idle High
+//
+#elif APPLICATION_MAX11131 // SPI interface default settings
+//
+//#define SPI_SCLK_Hz 48000000 // 48MHz
+//#define SPI_SCLK_Hz 24000000 // 24MHz
+#define SPI_SCLK_Hz 12000000 // 12MHz
+//#define SPI_SCLK_Hz 4000000 // 4MHz
+//#define SPI_SCLK_Hz 2000000 // 2MHz
+//#define SPI_SCLK_Hz 1000000 // 1MHz
+#define SPI_dataMode SPI_MODE3 // CPOL=1,CPHA=1: Rising Edge stable; SCLK idle High
+//
+#elif APPLICATION_MAX5171 // SPI interface default settings
+//
+//#define SPI_SCLK_Hz 48000000 // 48MHz
+//#define SPI_SCLK_Hz 24000000 // 24MHz
+#define SPI_SCLK_Hz 12000000 // 12MHz
+//#define SPI_SCLK_Hz 4000000 // 4MHz
+//#define SPI_SCLK_Hz 2000000 // 2MHz
+//#define SPI_SCLK_Hz 1000000 // 1MHz
+#define SPI_dataMode SPI_MODE3 // CPOL=1,CPHA=1: Rising Edge stable; SCLK idle High
+//
+#elif APPLICATION_MAX11410 // SPI interface default settings
+//
+//#define SPI_SCLK_Hz 48000000 // 48MHz
+//#define SPI_SCLK_Hz 24000000 // 24MHz
+//#define SPI_SCLK_Hz 12000000 // 12MHz
+#define SPI_SCLK_Hz 8000000 // 8MHz
+//#define SPI_SCLK_Hz 4000000 // 4MHz
+//#define SPI_SCLK_Hz 2000000 // 2MHz
+//#define SPI_SCLK_Hz 1000000 // 1MHz
+#define SPI_dataMode SPI_MODE0 // CPOL=0,CPHA=0: Falling Edge stable; SCLK idle Low
+//
+#elif APPLICATION_MAX12345 // SPI interface default settings
+//
+//#define SPI_SCLK_Hz 48000000 // 48MHz
+//#define SPI_SCLK_Hz 24000000 // 24MHz
+#define SPI_SCLK_Hz 12000000 // 12MHz
+//#define SPI_SCLK_Hz 4000000 // 4MHz
+//#define SPI_SCLK_Hz 2000000 // 2MHz
+//#define SPI_SCLK_Hz 1000000 // 1MHz
+#define SPI_dataMode SPI_MODE3 // CPOL=1,CPHA=1: Rising Edge stable; SCLK idle High
+//
+#else // APPLICATION_ArduinoPinsMonitor diagnostic
+//
+//#define SPI_SCLK_Hz 48000000 // 48MHz
+//#define SPI_SCLK_Hz 4000000 // 4MHz
+//#define SPI_SCLK_Hz 2000000 // 2MHz
+#define SPI_SCLK_Hz 1000000 // 1MHz
+//#define SPI_dataMode SPI_MODE0 // CPOL=0,CPHA=0: Rising Edge stable; SCLK idle Low
+//#define SPI_dataMode SPI_MODE1 // CPOL=0,CPHA=1: Falling Edge stable; SCLK idle Low
+//#define SPI_dataMode SPI_MODE2 // CPOL=1,CPHA=0: Falling Edge stable; SCLK idle High
+#define SPI_dataMode SPI_MODE3 // CPOL=1,CPHA=1: Rising Edge stable; SCLK idle High
+//
+#endif
+//
+uint32_t g_SPI_SCLK_Hz = SPI_SCLK_Hz;
+// TODO1: validate g_SPI_SCLK_Hz against system clock frequency SystemCoreClock F_CPU
+#if defined(TARGET_NUCLEO_F446RE) || defined(TARGET_NUCLEO_F401RE)
+// Nucleo SPI frequency isn't working quite as expected...
+// Looks like STMF4 has an spi clock prescaler (2,4,8,16,32,64,128,256)
+// so 180MHz->[90.0, 45.0, 22.5, 11.25, 5.625, 2.8125, 1.40625, 0.703125]
+// %SC SCLK=1MHz sets spi frequency 703.125kHz
+// %SC SCLK=2MHz sets spi frequency 1.40625MHz
+// %SC SCLK=3MHz sets spi frequency 2.8125MHz
+// %SC SCLK=6MHz sets spi frequency 5.625MHz
+// %SC SCLK=12MHz sets spi frequency 11.25MHz
+// %SC SCLK=23MHz sets spi frequency 22.5MHz
+// %SC SCLK=45MHz sets spi frequency 45.0MHz
+// Don't know why I can't reach spi frequency 90.0MHz, but ok whatever.
+const uint32_t limit_min_SPI_SCLK_divisor = 2;
+const uint32_t limit_max_SPI_SCLK_divisor = 256;
+// not really a divisor, just a powers-of-two prescaler with no intermediate divisors.
+#else
+const uint32_t limit_min_SPI_SCLK_divisor = 2;
+const uint32_t limit_max_SPI_SCLK_divisor = 8191;
+#endif
+const uint32_t limit_max_SPI_SCLK_Hz = (SystemCoreClock / limit_min_SPI_SCLK_divisor); // F_CPU / 2; // 8MHz / 2 = 4MHz
+const uint32_t limit_min_SPI_SCLK_Hz = (SystemCoreClock / limit_max_SPI_SCLK_divisor); // F_CPU / 128; // 8MHz / 128 = 62.5kHz
+//
+uint8_t g_SPI_dataMode = SPI_dataMode;
+uint8_t g_SPI_cs_state = 1;
+//
+#if defined(TARGET_MAX32630)
+// TODO1: avoid resource conflict between P5_0, P5_1, P5_2 SPI and DigitalInOut
+// void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
+//SPI spi0(SPI0_MOSI, SPI0_MISO, SPI0_SCK); // mosi, miso, sclk spi0 MAX32630FTHR: P0_5 P0_6 P0_4 ok but this is the microSD card, can't contact pins
+//SPI spi1(SPI1_MOSI, SPI1_MISO, SPI1_SCK); // mosi, miso, sclk spi1 MAX32630FTHR: P1_1 P1_2 P1_0 ok but this is the xip flash, can't contact pins
+//SPI spi2(SPI2_MOSI, SPI2_MISO, SPI2_SCK); // mosi, miso, sclk spi2 MAX32630FTHR: P5_1, P5_2, P5_0
+SPI spi(SPI2_MOSI, SPI2_MISO, SPI2_SCK); // mosi, miso, sclk spi2 MAX32630FTHR: P5_1, P5_2, P5_0
+//
+DigitalOut spi_cs(P3_0);
+#elif defined(TARGET_MAX32625MBED)
+// TODO1: avoid resource conflict between P5_0, P5_1, P5_2 SPI and DigitalInOut
+// void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
+//SPI spi(SPI0_MOSI, SPI0_MISO, SPI0_SCK); // mosi, miso, sclk spi0 TARGET_MAX32635MBED: P0_5 P0_6 P0_4 Arduino 8-pin header D5 D6 D7
+//DigitalOut spi_cs(SPI0_SS); // TARGET_MAX32635MBED: P0_7 Arduino 8-pin header D4
+SPI spi(SPI1_MOSI, SPI1_MISO, SPI1_SCK); // mosi, miso, sclk spi1 TARGET_MAX32635MBED: P1_1 P1_2 P1_0 Arduino 10-pin header D11 D12 D13
+DigitalOut spi_cs(SPI1_SS); // TARGET_MAX32635MBED: P1_3 Arduino 10-pin header D10
+SPI spi2_max541(SPI2_MOSI, SPI2_MISO, SPI2_SCK); // mosi, miso, sclk spi2 TARGET_MAX32635MBED: P2_5 P2_6 P2_4 Arduino 2x3-pin header; microSD
+DigitalOut spi2_max541_cs(SPI2_SS); // TARGET_MAX32635MBED: P2_7 Arduino 2x3-pin header
+#define HAS_SPI2_MAX541 1
+//
+#elif defined(TARGET_NUCLEO_F446RE) || defined(TARGET_NUCLEO_F401RE)
+// TODO1: avoid resource conflict between P5_0, P5_1, P5_2 SPI and DigitalInOut
+// void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
+//
+// TODO1: NUCLEO_F446RE SPI not working; CS and MOSI data looks OK but no SCLK clock pulses.
+SPI spi(SPI_MOSI, SPI_MISO, SPI_SCK); // mosi, miso, sclk spi1 TARGET_NUCLEO_F446RE: Arduino 10-pin header D11 D12 D13
+DigitalOut spi_cs(SPI_CS); // TARGET_NUCLEO_F446RE: PB_6 Arduino 10-pin header D10
+//
+#elif defined(TARGET_LPC1768)
+// TODO1: avoid resource conflict between P5_0, P5_1, P5_2 SPI and DigitalInOut
+// void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
+//SPI spi0(SPI0_MOSI, SPI0_MISO, SPI0_SCK); // mosi, miso, sclk spi0 MAX32630FTHR: P0_5 P0_6 P0_4 ok but this is the microSD card, can't contact pins
+//SPI spi1(SPI1_MOSI, SPI1_MISO, SPI1_SCK); // mosi, miso, sclk spi1 MAX32630FTHR: P1_1 P1_2 P1_0 ok but this is the xip flash, can't contact pins
+//SPI spi2(SPI2_MOSI, SPI2_MISO, SPI2_SCK); // mosi, miso, sclk spi2 MAX32630FTHR: P5_1, P5_2, P5_0
+SPI spi(SPI2_MOSI, SPI2_MISO, SPI2_SCK); // mosi, miso, sclk spi2 MAX32630FTHR: P5_1, P5_2, P5_0
+//
+DigitalOut spi_cs(P3_0);
+#else
+// unknown target
+#endif
+#endif
+
+//--------------------------------------------------
+// Device driver object
+#if APPLICATION_MAX5715 // SPI interface default settings
+DigitalOut LDACb_pin(D9);   // Arduino 10-pin header D9
+DigitalOut CLRb_pin(D8);    // Arduino 10-pin header D8
+//~ DigitalIn RDYb_pin(D12);     // Arduino 10-pin header D12 (MISO)
+MAX5715 g_MAX5715_device(spi, spi_cs,
+                         LDACb_pin,
+                         CLRb_pin,
+                         ///* RDYb_pin */ digitalInOut12,
+                         MAX5715::MAX5715_IC);
+//
+#elif APPLICATION_MAX11131 // SPI interface default settings
+DigitalOut CNVSTb_pin(D9);   // Arduino 10-pin header D9
+//DigitalOut CLRb_pin(D8);    // Arduino 10-pin header D8
+DigitalIn EOCb_pin(D12);     // Arduino 10-pin header D12 (MISO)
+MAX11131 g_MAX11131_device(spi, spi_cs,
+                           CNVSTb_pin,
+                           EOCb_pin,
+                           ///* RDYb_pin */ digitalInOut12,
+                           MAX11131::MAX11131_IC);
+//
+//
+#elif APPLICATION_MAX5171 // SPI interface default settings
+// AnalogOut FB_pin(Px_x_PortName_To_Be_Determined); // Analog Input to MAX5171 device
+DigitalOut RS_pin(D9); // Digital Configuration Input to MAX5171 device
+DigitalOut PDLb_pin(D8); // Digital Configuration Input to MAX5171 device
+DigitalOut CLRb_pin(D7); // Digital Configuration Input to MAX5171 device
+DigitalOut SHDN_pin(D6); // Digital Configuration Input to MAX5171 device
+// AnalogIn OUT_pin(A0); // Analog Output from MAX5171 device
+DigitalIn UPO_pin(D2); // Digital General-Purpose Output from MAX5171 device
+MAX5171 g_MAX5171_device(spi, spi_cs, RS_pin, PDLb_pin, CLRb_pin, SHDN_pin, UPO_pin, MAX5171::MAX5171_IC);
+//
+#elif APPLICATION_MAX11410 // SPI interface default settings
+//
+MAX11410 g_MAX11410_device(spi, spi_cs, MAX11410::MAX11410_IC);
+//
+#elif APPLICATION_MAX12345 // SPI interface default settings
+//
+MAX12345 g_MAX12345_device(spi, spi_cs, ...);
+//
+#else // APPLICATION_ArduinoPinsMonitor diagnostic
+//
+#endif
+
+
+//--------------------------------------------------
+// Option to dedicate I2C port pins
+//
+#ifndef HAS_I2C
+#define HAS_I2C 1
+#endif
+#if HAS_I2C
+//#include "I2C.h"
+//#include "I2CSlave.h"
+//#define I2C_SCL_Hz 400000 // 400kHz
+//#define I2C_SCL_Hz 200000 // 200kHz
+#define I2C_SCL_Hz 100000 // 100kHz
+//
+#if defined(TARGET_MAX32630)
+// TODO1: validate g_I2C_SCL_Hz against system clock frequency SystemCoreClock F_CPU
+const uint32_t limit_max_I2C_SCL_Hz = (SystemCoreClock / 2); // F_CPU / 2; // 8MHz / 2 = 4MHz
+const uint32_t limit_min_I2C_SCL_Hz = (SystemCoreClock / 8191); // F_CPU / 128; // 8MHz / 128 = 62.5kHz
+//
+// avoid resource conflict between P5_7, P6_0 I2C and DigitalInOut
+//I2C i2cMaster0(I2C0_SDA, I2C0_SCL); // sda scl MAX32630FTHR: NOT_CONNECTED
+//I2C i2cMaster1(I2C1_SDA, I2C1_SCL); // sda scl MAX32630FTHR: P3_4, P3_5
+//I2C i2cMaster2(I2C2_SDA, I2C2_SCL); // sda scl MAX32630FTHR: P5_7, P6_0
+//I2C i2cMaster(I2C2_SDA, I2C2_SCL); // sda scl MAX32630FTHR: P5_7, P6_0
+//
+//I2CSlave i2cSlave0(I2C0_SDA, I2C0_SCL); // sda scl MAX32630FTHR: NOT_CONNECTED
+//I2CSlave i2cSlave1(I2C1_SDA, I2C1_SCL); // sda scl MAX32630FTHR: P3_4, P3_5
+//I2CSlave i2cSlave2(I2C2_SDA, I2C2_SCL); // sda scl MAX32630FTHR: P5_7, P6_0
+#elif defined(TARGET_MAX32625MBED)
+// TODO1: validate g_I2C_SCL_Hz against system clock frequency SystemCoreClock F_CPU
+const uint32_t limit_max_I2C_SCL_Hz = (SystemCoreClock / 2); // F_CPU / 2; // 8MHz / 2 = 4MHz
+const uint32_t limit_min_I2C_SCL_Hz = (SystemCoreClock / 8191); // F_CPU / 128; // 8MHz / 128 = 62.5kHz
+//
+// avoid resource conflict between P5_7, P6_0 I2C and DigitalInOut
+//I2C i2cMaster0(I2C0_SDA, I2C0_SCL); // sda scl TARGET_MAX32635MBED: P1_6, P1_7 Arduino 10-pin header
+//I2C i2cMaster1(I2C1_SDA, I2C1_SCL); // sda scl TARGET_MAX32635MBED: P3_4, P3_5 Arduino 6-pin header
+// declare in narrower scope: MAX32625MBED I2C i2cMaster(I2C0_SDA, I2C0_SCL); // sda scl TARGET_MAX32635MBED: P1_6, P1_7 Arduino 10-pin header
+//
+#elif defined(TARGET_NUCLEO_F446RE)
+// TODO1: validate g_I2C_SCL_Hz against system clock frequency SystemCoreClock F_CPU
+const uint32_t limit_max_I2C_SCL_Hz = (SystemCoreClock / 2); // F_CPU / 2; // 8MHz / 2 = 4MHz
+const uint32_t limit_min_I2C_SCL_Hz = (SystemCoreClock / 8191); // F_CPU / 128; // 8MHz / 128 = 62.5kHz
+//
+// avoid resource conflict between P5_7, P6_0 I2C and DigitalInOut
+//I2C i2cMaster0(I2C0_SDA, I2C0_SCL); // sda scl TARGET_MAX32635MBED: P1_6, P1_7 Arduino 10-pin header
+//I2C i2cMaster1(I2C1_SDA, I2C1_SCL); // sda scl TARGET_MAX32635MBED: P3_4, P3_5 Arduino 6-pin header
+// declare in narrower scope: MAX32625MBED I2C i2cMaster(I2C0_SDA, I2C0_SCL); // sda scl TARGET_MAX32635MBED: P1_6, P1_7 Arduino 10-pin header
+# ifndef I2C0_SDA
+#  define I2C0_SDA I2C_SDA
+#  define I2C0_SCL I2C_SCL
+# endif
+//
+#elif defined(TARGET_NUCLEO_F401RE)
+// TODO1: validate g_I2C_SCL_Hz against system clock frequency SystemCoreClock F_CPU
+const uint32_t limit_max_I2C_SCL_Hz = (SystemCoreClock / 2); // F_CPU / 2; // 8MHz / 2 = 4MHz
+const uint32_t limit_min_I2C_SCL_Hz = (SystemCoreClock / 8191); // F_CPU / 128; // 8MHz / 128 = 62.5kHz
+//
+// avoid resource conflict between P5_7, P6_0 I2C and DigitalInOut
+//I2C i2cMaster0(I2C0_SDA, I2C0_SCL); // sda scl TARGET_MAX32635MBED: P1_6, P1_7 Arduino 10-pin header
+//I2C i2cMaster1(I2C1_SDA, I2C1_SCL); // sda scl TARGET_MAX32635MBED: P3_4, P3_5 Arduino 6-pin header
+// declare in narrower scope: MAX32625MBED I2C i2cMaster(I2C0_SDA, I2C0_SCL); // sda scl TARGET_MAX32635MBED: P1_6, P1_7 Arduino 10-pin header
+# ifndef I2C0_SDA
+#  define I2C0_SDA I2C_SDA
+#  define I2C0_SCL I2C_SCL
+# endif
+//
+#elif defined(TARGET_LPC1768)
+#else
+// unknown target
+#endif
+//
+#endif
+#if HAS_I2C
+uint32_t g_I2C_SCL_Hz = I2C_SCL_Hz;
+uint8_t g_I2C_status = 0; // g_I2C_status = Wire_Sr.endTransmission();
+uint8_t g_I2C_deviceAddress7 = (0xA0 >> 1); // I2C device address (slave address on I2C bus), 7-bits, RIGHT-justified.
+uint8_t g_I2C_read_count = 0;
+uint8_t g_I2C_write_count = 0;
+uint8_t g_I2C_write_data[256];
+uint8_t g_I2C_command_regAddress;
+//
+// TODO: i2c init
+// i2cMaster.frequency(g_I2C_SCL_Hz);
+#endif
+#if HAS_I2C
+// TODO: i2c transfer
+//const int addr7bit = 0x48;      // 7 bit I2C address
+//const int addr8bit = 0x48 << 1; // 8bit I2C address, 0x90
+// /* int  */   i2cMaster.read (int addr8bit, char *data, int length, bool repeated=false) // Read from an I2C slave.
+// /* int  */   i2cMaster.read (int ack) // Read a single byte from the I2C bus.
+// /* int  */   i2cMaster.write (int addr8bit, const char *data, int length, bool repeated=false) // Write to an I2C slave.
+// /* int  */   i2cMaster.write (int data) // Write single byte out on the I2C bus.
+// /* void */   i2cMaster.start (void) // Creates a start condition on the I2C bus.
+// /* void */   i2cMaster.stop (void) // Creates a stop condition on the I2C bus.
+// /* int */    i2cMaster.transfer (int addr8bit, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length, const event_callback_t &callback, int event=I2C_EVENT_TRANSFER_COMPLETE, bool repeated=false) // Start nonblocking I2C transfer. More...
+// /* void */   i2cMaster.abort_transfer () // Abort the ongoing I2C transfer. More...
+#endif
+
+
+//--------------------------------------------------
+// Declare the Serial driver
+// default baud rate settings are 9600 8N1
+// install device driver from http://developer.mbed.org/media/downloads/drivers/mbedWinSerial_16466.exe
+// see docs https://docs.mbed.com/docs/mbed-os-handbook/en/5.5/getting_started/what_need/
+#if defined(TARGET_MAX32630)
+    #include "USBSerial.h"
+// Hardware serial port over DAPLink
+// The default baud rate for the DapLink UART is 9600
+Serial DAPLINKserial(P2_1, P2_0);     // tx, rx
+    #define HAS_DAPLINK_SERIAL 1
+// Virtual serial port over USB
+// The baud rate does not affect the virtual USBSerial UART.
+USBSerial microUSBserial;
+    #define HAS_MICROUSBSERIAL 1
+//--------------------------------------------------
+#elif defined(TARGET_MAX32625MBED)
+    #include "USBSerial.h"
+// Hardware serial port over DAPLink
+// The default baud rate for the DapLink UART is 9600
+Serial DAPLINKserial(P2_1, P2_0);     // tx, rx
+    #define HAS_DAPLINK_SERIAL 1
+// Virtual serial port over USB
+// The baud rate does not affect the virtual USBSerial UART.
+USBSerial microUSBserial;
+    #define HAS_MICROUSBSERIAL 1
+//--------------------------------------------------
+#elif defined(TARGET_NUCLEO_F446RE) || defined(TARGET_NUCLEO_F401RE)
+Serial microUSBserial(SERIAL_TX, SERIAL_RX);     // tx, rx
+    #define HAS_MICROUSBSERIAL 1
+//--------------------------------------------------
+// TODO1: TARGET=MAX32625MBED ARM Cortex-M4F 96MHz 512kB Flash 160kB SRAM
+#elif defined(TARGET_LPC1768)
+Serial microUSBserial(USBTX, USBRX);     // tx, rx
+    #define HAS_MICROUSBSERIAL 1
+#else
+// unknown target
+#endif
+
+void on_immediate_0x21(); // Unicode (U+0021) ! EXCLAMATION MARK
+void on_immediate_0x7b(); // Unicode (U+007B) { LEFT CURLY BRACKET
+void on_immediate_0x7d(); // Unicode (U+007D) } RIGHT CURLY BRACKET
+
+//--------------------------------------------------
+// Option to process command buffer from microUSBserial or DAPLINKserial
+#ifndef USE_COMMAND_BUFFER
+#define USE_COMMAND_BUFFER 1
+#endif
+#if USE_COMMAND_BUFFER
+#include "CmdLine.h"
+
+# if HAS_DAPLINK_SERIAL
+CmdLine cmdLine_DAPLINKserial(DAPLINKserial, "DAPLINK");
+# endif // HAS_DAPLINK_SERIAL
+// TODO1: diagnostic: define HAS_MICROUSBSERIAL 0
+//~ #define HAS_MICROUSBSERIAL 0
+# if HAS_MICROUSBSERIAL
+CmdLine cmdLine_microUSBserial(microUSBserial, "microUSB");
+# endif // HAS_MICROUSBSERIAL
+
+#endif // USE_COMMAND_BUFFER
+
+//--------------------------------------------------
+// tolerate AT commands, which may be sent during probe, such as:
+//  AT
+//  AT+CGMI      -- request manufacturer identification AT+CMGI=?
+//  AT+CGMM      -- request manufacturer model
+//  AT%IPSYS?
+//  ATE0         -- echo disable
+//  ATV1         -- verbose result codes OK | ERROR | NO CARRIER
+//  AT+CMEE=1
+//  ATX4
+//  AT&C1
+//  ATE0
+//  AT+CMEE=1
+//  AT+GCAP
+//  ATI
+//  AT+CPIN?
+//  AT+CGMM
+#ifndef IGNORE_AT_COMMANDS
+#define IGNORE_AT_COMMANDS 1
+#endif
+
+
+// uncrustify-0.66.1 *INDENT-OFF*
+//--------------------------------------------------
+// Declare the DigitalInOut GPIO pins
+// Optional digitalInOut support. If there is only one it should be digitalInOut1.
+// D) Digital High/Low/Input Pin
+#if defined(TARGET_MAX32630)
+//       +-------------[microUSB]-------------+
+//       | J1         MAX32630FTHR        J2  |
+//       | [ ] RST                    GND [ ] |
+//       | [ ] 3V3                    BAT+[ ] |
+//       | [ ] 1V8                  reset SW1 |
+//       | [ ] GND       J4               J3  |
+//       | [ ] AIN_0 1.2Vfs     (bat) SYS [ ] |
+//       | [ ] AIN_1 1.2Vfs           PWR [ ] |
+//       | [ ] AIN_2 1.2Vfs      +5V VBUS [ ] |
+//       | [ ] AIN_3 1.2Vfs   1-WIRE P4_0 [ ] | dig9
+// dig10 | [x] P5_7  SDA2        SRN P5_6 [ ] | dig8
+// dig11 | [x] P6_0  SCL2      SDIO3 P5_5 [ ] | dig7
+// dig12 | [x] P5_0  SCLK      SDIO2 P5_4 [ ] | dig6
+// dig13 | [x] P5_1  MOSI       SSEL P5_3 [x] | dig5
+// dig14 | [ ] P5_2  MISO        RTS P3_3 [ ] | dig4
+// dig15 | [ ] P3_0  RX          CTS P3_2 [ ] | dig3
+// dig0  | [ ] P3_1  TX          SCL P3_5 [x] | dig2
+//       | [ ] GND               SDA P3_4 [x] | dig1
+//       +------------------------------------+
+    #define HAS_digitalInOut0 1 // P3_1 TARGET_MAX32630 J1.15
+    #define HAS_digitalInOut1 1 // P3_4 TARGET_MAX32630 J3.12
+    #define HAS_digitalInOut2 1 // P3_5 TARGET_MAX32630 J3.11
+    #define HAS_digitalInOut3 1 // P3_2 TARGET_MAX32630 J3.10
+    #define HAS_digitalInOut4 1 // P3_3 TARGET_MAX32630 J3.9
+    #define HAS_digitalInOut5 1 // P5_3 TARGET_MAX32630 J3.8
+    #define HAS_digitalInOut6 1 // P5_4 TARGET_MAX32630 J3.7
+    #define HAS_digitalInOut7 1 // P5_5 TARGET_MAX32630 J3.6
+    #define HAS_digitalInOut8 1 // P5_6 TARGET_MAX32630 J3.5
+    #define HAS_digitalInOut9 1 // P4_0 TARGET_MAX32630 J3.4
+#if HAS_I2C
+// avoid resource conflict between P5_7, P6_0 I2C and DigitalInOut
+    #define HAS_digitalInOut10 0 // P5_7 TARGET_MAX32630 J1.9
+    #define HAS_digitalInOut11 0 // P6_0 TARGET_MAX32630 J1.10
+#else // HAS_I2C
+    #define HAS_digitalInOut10 1 // P5_7 TARGET_MAX32630 J1.9
+    #define HAS_digitalInOut11 1 // P6_0 TARGET_MAX32630 J1.10
+#endif // HAS_I2C
+#if HAS_SPI
+// avoid resource conflict between P5_0, P5_1, P5_2 SPI and DigitalInOut
+    #define HAS_digitalInOut12 0 // P5_0 TARGET_MAX32630 J1.11
+    #define HAS_digitalInOut13 0 // P5_1 TARGET_MAX32630 J1.12
+    #define HAS_digitalInOut14 0 // P5_2 TARGET_MAX32630 J1.13
+    #define HAS_digitalInOut15 0 // P3_0 TARGET_MAX32630 J1.14
+#else // HAS_SPI
+    #define HAS_digitalInOut12 1 // P5_0 TARGET_MAX32630 J1.11
+    #define HAS_digitalInOut13 1 // P5_1 TARGET_MAX32630 J1.12
+    #define HAS_digitalInOut14 1 // P5_2 TARGET_MAX32630 J1.13
+    #define HAS_digitalInOut15 1 // P3_0 TARGET_MAX32630 J1.14
+#endif // HAS_SPI
+#if HAS_digitalInOut0
+    DigitalInOut digitalInOut0(P3_1, PIN_INPUT, PullUp, 1); // P3_1 TARGET_MAX32630 J1.15
+#endif
+#if HAS_digitalInOut1
+    DigitalInOut digitalInOut1(P3_4, PIN_INPUT, PullUp, 1); // P3_4 TARGET_MAX32630 J3.12
+#endif
+#if HAS_digitalInOut2
+    DigitalInOut digitalInOut2(P3_5, PIN_INPUT, PullUp, 1); // P3_5 TARGET_MAX32630 J3.11
+#endif
+#if HAS_digitalInOut3
+    DigitalInOut digitalInOut3(P3_2, PIN_INPUT, PullUp, 1); // P3_2 TARGET_MAX32630 J3.10
+#endif
+#if HAS_digitalInOut4
+    DigitalInOut digitalInOut4(P3_3, PIN_INPUT, PullUp, 1); // P3_3 TARGET_MAX32630 J3.9
+#endif
+#if HAS_digitalInOut5
+    DigitalInOut digitalInOut5(P5_3, PIN_INPUT, PullUp, 1); // P5_3 TARGET_MAX32630 J3.8
+#endif
+#if HAS_digitalInOut6
+    DigitalInOut digitalInOut6(P5_4, PIN_INPUT, PullUp, 1); // P5_4 TARGET_MAX32630 J3.7
+#endif
+#if HAS_digitalInOut7
+    DigitalInOut digitalInOut7(P5_5, PIN_INPUT, PullUp, 1); // P5_5 TARGET_MAX32630 J3.6
+#endif
+#if HAS_digitalInOut8
+    DigitalInOut digitalInOut8(P5_6, PIN_INPUT, PullUp, 1); // P5_6 TARGET_MAX32630 J3.5
+#endif
+#if HAS_digitalInOut9
+    DigitalInOut digitalInOut9(P4_0, PIN_INPUT, PullUp, 1); // P4_0 TARGET_MAX32630 J3.4
+#endif
+#if HAS_digitalInOut10
+    DigitalInOut digitalInOut10(P5_7, PIN_INPUT, PullUp, 1); // P5_7 TARGET_MAX32630 J1.9
+#endif
+#if HAS_digitalInOut11
+    DigitalInOut digitalInOut11(P6_0, PIN_INPUT, PullUp, 1); // P6_0 TARGET_MAX32630 J1.10
+#endif
+#if HAS_digitalInOut12
+    DigitalInOut digitalInOut12(P5_0, PIN_INPUT, PullUp, 1); // P5_0 TARGET_MAX32630 J1.11
+#endif
+#if HAS_digitalInOut13
+    DigitalInOut digitalInOut13(P5_1, PIN_INPUT, PullUp, 1); // P5_1 TARGET_MAX32630 J1.12
+#endif
+#if HAS_digitalInOut14
+    DigitalInOut digitalInOut14(P5_2, PIN_INPUT, PullUp, 1); // P5_2 TARGET_MAX32630 J1.13
+#endif
+#if HAS_digitalInOut15
+    DigitalInOut digitalInOut15(P3_0, PIN_INPUT, PullUp, 1); // P3_0 TARGET_MAX32630 J1.14
+#endif
+//--------------------------------------------------
+#elif defined(TARGET_MAX32625MBED)
+// TARGET=MAX32625MBED ARM Cortex-M4F 96MHz 512kB Flash 160kB SRAM
+//             +-------------------------------------+
+//             |   MAX32625MBED Arduino UNO header   |
+//             |                                     |
+//             |                           A5/SCL[ ] |   P1_7 dig15
+//             |                           A4/SDA[ ] |   P1_6 dig14
+//             |                         AREF=N/C[ ] |
+//             |                              GND[ ] |
+//             | [ ]N/C                    SCK/13[ ] |   P1_0 dig13
+//             | [ ]IOREF=3V3             MISO/12[ ] |   P1_2 dig12
+//             | [ ]RST                   MOSI/11[ ]~|   P1_1 dig11
+//             | [ ]3V3                     CS/10[ ]~|   P1_3 dig10
+//             | [ ]5V0                         9[ ]~|   P1_5 dig9
+//             | [ ]GND                         8[ ] |   P1_4 dig8
+//             | [ ]GND                              |
+//             | [ ]Vin                         7[ ] |   P0_7 dig7
+//             |                                6[ ]~|   P0_6 dig6
+//       AIN_0 | [ ]A0                          5[ ]~|   P0_5 dig5
+//       AIN_1 | [ ]A1                          4[ ] |   P0_4 dig4
+//       AIN_2 | [ ]A2                     INT1/3[ ]~|   P0_3 dig3
+//       AIN_3 | [ ]A3                     INT0/2[ ] |   P0_2 dig2
+// dig16  P3_4 | [ ]A4/SDA  RST SCK MISO     TX>1[ ] |   P0_1 dig1
+// dig17  P3_5 | [ ]A5/SCL  [ ] [ ] [ ]      RX<0[ ] |   P0_0 dig0
+//             |            [ ] [ ] [ ]              |
+//             |  UNO_R3    GND MOSI 5V  ____________/
+//              \_______________________/
+//
+    #define HAS_digitalInOut0 1 // P0_0 TARGET_MAX32625MBED D0
+    #define HAS_digitalInOut1 1 // P0_1 TARGET_MAX32625MBED D1
+#if APPLICATION_MAX11131
+    #define HAS_digitalInOut2 0 // P0_2 TARGET_MAX32625MBED D2 -- MAX11131 EOC DigitalIn
+#else
+    #define HAS_digitalInOut2 1 // P0_2 TARGET_MAX32625MBED D2
+#endif
+    #define HAS_digitalInOut3 1 // P0_3 TARGET_MAX32625MBED D3
+    #define HAS_digitalInOut4 1 // P0_4 TARGET_MAX32625MBED D4
+    #define HAS_digitalInOut5 1 // P0_5 TARGET_MAX32625MBED D5
+    #define HAS_digitalInOut6 1 // P0_6 TARGET_MAX32625MBED D6
+    #define HAS_digitalInOut7 1 // P0_7 TARGET_MAX32625MBED D7
+    #define HAS_digitalInOut8 1 // P1_4 TARGET_MAX32625MBED D8
+#if APPLICATION_MAX11131
+    #define HAS_digitalInOut9 0 // P1_5 TARGET_MAX32625MBED D9 -- MAX11131 CNVST DigitalOut
+#else
+    #define HAS_digitalInOut9 1 // P1_5 TARGET_MAX32625MBED D9
+#endif
+#if HAS_SPI
+// avoid resource conflict between P5_0, P5_1, P5_2 SPI and DigitalInOut
+    #define HAS_digitalInOut10 0 // P1_3 TARGET_MAX32635MBED CS/10
+    #define HAS_digitalInOut11 0 // P1_1 TARGET_MAX32635MBED MOSI/11
+    #define HAS_digitalInOut12 0 // P1_2 TARGET_MAX32635MBED MISO/12
+    #define HAS_digitalInOut13 0 // P1_0 TARGET_MAX32635MBED SCK/13
+#else // HAS_SPI
+    #define HAS_digitalInOut10 1 // P1_3 TARGET_MAX32635MBED CS/10
+    #define HAS_digitalInOut11 1 // P1_1 TARGET_MAX32635MBED MOSI/11
+    #define HAS_digitalInOut12 1 // P1_2 TARGET_MAX32635MBED MISO/12
+    #define HAS_digitalInOut13 1 // P1_0 TARGET_MAX32635MBED SCK/13
+#endif // HAS_SPI
+#if HAS_I2C
+// avoid resource conflict between P5_7, P6_0 I2C and DigitalInOut
+    #define HAS_digitalInOut14 0 // P1_6 TARGET_MAX32635MBED A4/SDA (10pin digital connector)
+    #define HAS_digitalInOut15 0 // P1_7 TARGET_MAX32635MBED A5/SCL (10pin digital connector)
+    #define HAS_digitalInOut16 0 // P3_4 TARGET_MAX32635MBED A4/SDA (6pin analog connector)
+    #define HAS_digitalInOut17 0 // P3_5 TARGET_MAX32635MBED A5/SCL (6pin analog connector)
+#else // HAS_I2C
+    #define HAS_digitalInOut14 1 // P1_6 TARGET_MAX32635MBED A4/SDA (10pin digital connector)
+    #define HAS_digitalInOut15 1 // P1_7 TARGET_MAX32635MBED A5/SCL (10pin digital connector)
+    #define HAS_digitalInOut16 1 // P3_4 TARGET_MAX32635MBED A4/SDA (6pin analog connector)
+    #define HAS_digitalInOut17 1 // P3_5 TARGET_MAX32635MBED A5/SCL (6pin analog connector)
+#endif // HAS_I2C
+#if HAS_digitalInOut0
+    DigitalInOut digitalInOut0(P0_0, PIN_INPUT, PullUp, 1); // P0_0 TARGET_MAX32625MBED D0
+#endif
+#if HAS_digitalInOut1
+    DigitalInOut digitalInOut1(P0_1, PIN_INPUT, PullUp, 1); // P0_1 TARGET_MAX32625MBED D1
+#endif
+#if HAS_digitalInOut2
+    DigitalInOut digitalInOut2(P0_2, PIN_INPUT, PullUp, 1); // P0_2 TARGET_MAX32625MBED D2
+#endif
+#if HAS_digitalInOut3
+    DigitalInOut digitalInOut3(P0_3, PIN_INPUT, PullUp, 1); // P0_3 TARGET_MAX32625MBED D3
+#endif
+#if HAS_digitalInOut4
+    DigitalInOut digitalInOut4(P0_4, PIN_INPUT, PullUp, 1); // P0_4 TARGET_MAX32625MBED D4
+#endif
+#if HAS_digitalInOut5
+    DigitalInOut digitalInOut5(P0_5, PIN_INPUT, PullUp, 1); // P0_5 TARGET_MAX32625MBED D5
+#endif
+#if HAS_digitalInOut6
+    DigitalInOut digitalInOut6(P0_6, PIN_INPUT, PullUp, 1); // P0_6 TARGET_MAX32625MBED D6
+#endif
+#if HAS_digitalInOut7
+    DigitalInOut digitalInOut7(P0_7, PIN_INPUT, PullUp, 1); // P0_7 TARGET_MAX32625MBED D7
+#endif
+#if HAS_digitalInOut8
+    DigitalInOut digitalInOut8(P1_4, PIN_INPUT, PullUp, 1); // P1_4 TARGET_MAX32625MBED D8
+#endif
+#if HAS_digitalInOut9
+    DigitalInOut digitalInOut9(P1_5, PIN_INPUT, PullUp, 1); // P1_5 TARGET_MAX32625MBED D9
+#endif
+#if HAS_digitalInOut10
+    DigitalInOut digitalInOut10(P1_3, PIN_INPUT, PullUp, 1); // P1_3 TARGET_MAX32635MBED CS/10
+#endif
+#if HAS_digitalInOut11
+    DigitalInOut digitalInOut11(P1_1, PIN_INPUT, PullUp, 1); // P1_1 TARGET_MAX32635MBED MOSI/11
+#endif
+#if HAS_digitalInOut12
+    DigitalInOut digitalInOut12(P1_2, PIN_INPUT, PullUp, 1); // P1_2 TARGET_MAX32635MBED MISO/12
+#endif
+#if HAS_digitalInOut13
+    DigitalInOut digitalInOut13(P1_0, PIN_INPUT, PullUp, 1); // P1_0 TARGET_MAX32635MBED SCK/13
+#endif
+#if HAS_digitalInOut14
+    // Ensure that the unused I2C pins do not interfere with analog inputs A4 and A5
+    // DigitalInOut mode can be one of PullUp, PullDown, PullNone, OpenDrain
+    DigitalInOut digitalInOut14(P1_6, PIN_INPUT, OpenDrain, 1); // P1_6 TARGET_MAX32635MBED A4/SDA (10pin digital connector)
+#endif
+#if HAS_digitalInOut15
+    // Ensure that the unused I2C pins do not interfere with analog inputs A4 and A5
+    DigitalInOut digitalInOut15(P1_7, PIN_INPUT, OpenDrain, 1); // P1_7 TARGET_MAX32635MBED A5/SCL (10pin digital connector)
+#endif
+#if HAS_digitalInOut16
+    // Ensure that the unused I2C pins do not interfere with analog inputs A4 and A5
+    // DigitalInOut mode can be one of PullUp, PullDown, PullNone, OpenDrain
+    // PullUp-->3.4V, PullDown-->1.7V, PullNone-->3.5V, OpenDrain-->0.00V
+    DigitalInOut digitalInOut16(P3_4, PIN_INPUT, OpenDrain, 0); // P3_4 TARGET_MAX32635MBED A4/SDA (6pin analog connector)
+#endif
+#if HAS_digitalInOut17
+    // Ensure that the unused I2C pins do not interfere with analog inputs A4 and A5
+    DigitalInOut digitalInOut17(P3_5, PIN_INPUT, OpenDrain, 0); // P3_5 TARGET_MAX32635MBED A5/SCL (6pin analog connector)
+#endif
+//--------------------------------------------------
+#elif defined(TARGET_NUCLEO_F446RE) || defined(TARGET_NUCLEO_F401RE)
+    #define HAS_digitalInOut0 0 // P0_0 TARGET_MAX32625MBED D0
+    #define HAS_digitalInOut1 0 // P0_1 TARGET_MAX32625MBED D1
+#if APPLICATION_MAX11131
+    #define HAS_digitalInOut2 0 // P0_2 TARGET_MAX32625MBED D2 -- MAX11131 EOC DigitalIn
+#else
+    #define HAS_digitalInOut2 1 // P0_2 TARGET_MAX32625MBED D2
+#endif
+    #define HAS_digitalInOut3 1 // P0_3 TARGET_MAX32625MBED D3
+    #define HAS_digitalInOut4 1 // P0_4 TARGET_MAX32625MBED D4
+    #define HAS_digitalInOut5 1 // P0_5 TARGET_MAX32625MBED D5
+    #define HAS_digitalInOut6 1 // P0_6 TARGET_MAX32625MBED D6
+    #define HAS_digitalInOut7 1 // P0_7 TARGET_MAX32625MBED D7
+#if APPLICATION_MAX5715
+    #define HAS_digitalInOut8 0 // P1_4 TARGET_MAX32625MBED D8 -- MAX5715 CLRb DigitalOut
+#else
+    #define HAS_digitalInOut8 1 // P1_4 TARGET_MAX32625MBED D8
+#endif
+#if APPLICATION_MAX5715
+    #define HAS_digitalInOut9 0 // P1_5 TARGET_MAX32625MBED D9 -- MAX5715 LDACb DigitalOut
+#elif APPLICATION_MAX11131
+    #define HAS_digitalInOut9 0 // P1_5 TARGET_MAX32625MBED D9 -- MAX11131 CNVST DigitalOut
+#else
+    #define HAS_digitalInOut9 1 // P1_5 TARGET_MAX32625MBED D9
+#endif
+#if HAS_SPI
+// avoid resource conflict between P5_0, P5_1, P5_2 SPI and DigitalInOut
+    // Arduino digital pin D10 SPI function is CS/10
+    // Arduino digital pin D11 SPI function is MOSI/11
+    // Arduino digital pin D12 SPI function is MISO/12
+    // Arduino digital pin D13 SPI function is SCK/13
+    #define HAS_digitalInOut10 0
+    #define HAS_digitalInOut11 0
+    #define HAS_digitalInOut12 0
+    #define HAS_digitalInOut13 0
+#else // HAS_SPI
+    #define HAS_digitalInOut10 1
+    #define HAS_digitalInOut11 1
+    #define HAS_digitalInOut12 1
+    #define HAS_digitalInOut13 1
+#endif // HAS_SPI
+#if HAS_I2C
+// avoid resource conflict between P5_7, P6_0 I2C and DigitalInOut
+    // Arduino digital pin D14 I2C function is A4/SDA (10pin digital connector)
+    // Arduino digital pin D15 I2C function is A5/SCL (10pin digital connector)
+    // Arduino digital pin D16 I2C function is A4/SDA (6pin analog connector)
+    // Arduino digital pin D17 I2C function is A5/SCL (6pin analog connector)
+    #define HAS_digitalInOut14 0
+    #define HAS_digitalInOut15 0
+    #define HAS_digitalInOut16 0
+    #define HAS_digitalInOut17 0
+#else // HAS_I2C
+    #define HAS_digitalInOut14 1
+    #define HAS_digitalInOut15 1
+    #define HAS_digitalInOut16 0
+    #define HAS_digitalInOut17 0
+#endif // HAS_I2C
+#if HAS_digitalInOut0
+    DigitalInOut digitalInOut0(D0, PIN_INPUT, PullUp, 1);
+#endif
+#if HAS_digitalInOut1
+    DigitalInOut digitalInOut1(D1, PIN_INPUT, PullUp, 1);
+#endif
+#if HAS_digitalInOut2
+    DigitalInOut digitalInOut2(D2, PIN_INPUT, PullUp, 1);
+#endif
+#if HAS_digitalInOut3
+    DigitalInOut digitalInOut3(D3, PIN_INPUT, PullUp, 1);
+#endif
+#if HAS_digitalInOut4
+    DigitalInOut digitalInOut4(D4, PIN_INPUT, PullUp, 1);
+#endif
+#if HAS_digitalInOut5
+    DigitalInOut digitalInOut5(D5, PIN_INPUT, PullUp, 1);
+#endif
+#if HAS_digitalInOut6
+    DigitalInOut digitalInOut6(D6, PIN_INPUT, PullUp, 1);
+#endif
+#if HAS_digitalInOut7
+    DigitalInOut digitalInOut7(D7, PIN_INPUT, PullUp, 1);
+#endif
+#if HAS_digitalInOut8
+    DigitalInOut digitalInOut8(D8, PIN_INPUT, PullUp, 1);
+#endif
+#if HAS_digitalInOut9
+    DigitalInOut digitalInOut9(D9, PIN_INPUT, PullUp, 1);
+#endif
+#if HAS_digitalInOut10
+    // Arduino digital pin D10 SPI function is CS/10
+    DigitalInOut digitalInOut10(D10, PIN_INPUT, PullUp, 1);
+#endif
+#if HAS_digitalInOut11
+    // Arduino digital pin D11 SPI function is MOSI/11
+    DigitalInOut digitalInOut11(D11, PIN_INPUT, PullUp, 1);
+#endif
+#if HAS_digitalInOut12
+    // Arduino digital pin D12 SPI function is MISO/12
+    DigitalInOut digitalInOut12(D12, PIN_INPUT, PullUp, 1);
+#endif
+#if HAS_digitalInOut13
+    // Arduino digital pin D13 SPI function is SCK/13
+    DigitalInOut digitalInOut13(D13, PIN_INPUT, PullUp, 1);
+#endif
+#if HAS_digitalInOut14
+    // Arduino digital pin D14 I2C function is A4/SDA (10pin digital connector)
+    DigitalInOut digitalInOut14(D14, PIN_INPUT, PullUp, 1);
+#endif
+#if HAS_digitalInOut15
+    // Arduino digital pin D15 I2C function is A5/SCL (10pin digital connector)
+    DigitalInOut digitalInOut15(D15, PIN_INPUT, PullUp, 1);
+#endif
+#if HAS_digitalInOut16
+    // Arduino digital pin D16 I2C function is A4/SDA (6pin analog connector)
+    DigitalInOut digitalInOut16(D16, PIN_INPUT, PullUp, 1);
+#endif
+#if HAS_digitalInOut17
+    // Arduino digital pin D17 I2C function is A5/SCL (6pin analog connector)
+    DigitalInOut digitalInOut17(D17, PIN_INPUT, PullUp, 1);
+#endif
+//--------------------------------------------------
+#elif defined(TARGET_LPC1768)
+    #define HAS_digitalInOut0 1
+    #define HAS_digitalInOut1 1
+    #define HAS_digitalInOut2 1
+    #define HAS_digitalInOut3 1
+    #define HAS_digitalInOut4 1
+    #define HAS_digitalInOut5 1
+    #define HAS_digitalInOut6 1
+    #define HAS_digitalInOut7 1
+    #define HAS_digitalInOut8 1
+    #define HAS_digitalInOut9 1
+//    #define HAS_digitalInOut10 1
+//    #define HAS_digitalInOut11 1
+//    #define HAS_digitalInOut12 1
+//    #define HAS_digitalInOut13 1
+//    #define HAS_digitalInOut14 1
+//    #define HAS_digitalInOut15 1
+#if HAS_digitalInOut0
+    DigitalInOut digitalInOut0(p5, PIN_INPUT, PullUp, 1); // TARGET_LPC1768 P0.9/I2STX_SDA/MOSI1/MAT2.3
+#endif
+#if HAS_digitalInOut1
+    DigitalInOut digitalInOut1(p6, PIN_INPUT, PullUp, 1); // TARGET_LPC1768 P0.8/I2STX_WS/MISO1/MAT2.2
+#endif
+#if HAS_digitalInOut2
+    DigitalInOut digitalInOut2(p7, PIN_INPUT, PullUp, 1); // TARGET_LPC1768 P0.7/I2STX_CLK/SCK1/MAT2.1
+#endif
+#if HAS_digitalInOut3
+    DigitalInOut digitalInOut3(p8, PIN_INPUT, PullUp, 1); // TARGET_LPC1768 P0.6/I2SRX_SDA/SSEL1/MAT2.0
+#endif
+#if HAS_digitalInOut4
+    DigitalInOut digitalInOut4(p9, PIN_INPUT, PullUp, 1); // TARGET_LPC1768 P0.0/CAN_RX1/TXD3/SDA1
+#endif
+#if HAS_digitalInOut5
+    DigitalInOut digitalInOut5(p10, PIN_INPUT, PullUp, 1); // TARGET_LPC1768 P0.1/CAN_TX1/RXD3/SCL1
+#endif
+#if HAS_digitalInOut6
+    DigitalInOut digitalInOut6(p11, PIN_INPUT, PullUp, 1); // TARGET_LPC1768 P0.18/DCD1/MOSI0/MOSI1
+#endif
+#if HAS_digitalInOut7
+    DigitalInOut digitalInOut7(p12, PIN_INPUT, PullUp, 1); // TARGET_LPC1768 P0.17/CTS1/MISO0/MISO
+#endif
+#if HAS_digitalInOut8
+    DigitalInOut digitalInOut8(p13, PIN_INPUT, PullUp, 1); // TARGET_LPC1768 P0.15/TXD1/SCK0/SCK
+#endif
+#if HAS_digitalInOut9
+    DigitalInOut digitalInOut9(p14, PIN_INPUT, PullUp, 1); // TARGET_LPC1768 P0.16/RXD1/SSEL0/SSEL
+#endif
+    //
+    // these pins support analog input analogIn0 .. analogIn5
+    //DigitalInOut digitalInOut_(p15, PIN_INPUT, PullUp, 1); // TARGET_LPC1768 P0.23/AD0.0/I2SRX_CLK/CAP3.0
+    //DigitalInOut digitalInOut_(p16, PIN_INPUT, PullUp, 1); // TARGET_LPC1768 P0.24/AD0.1/I2SRX_WS/CAP3.1
+    //DigitalInOut digitalInOut_(p17, PIN_INPUT, PullUp, 1); // TARGET_LPC1768 P0.25/AD0.2/I2SRX_SDA/TXD3
+    //DigitalInOut digitalInOut_(p18, PIN_INPUT, PullUp, 1); // TARGET_LPC1768 P0.26/AD0.3/AOUT/RXD3
+    //DigitalInOut digitalInOut_(p19, PIN_INPUT, PullUp, 1); // TARGET_LPC1768 P1.30/VBUS/AD0.4
+    //DigitalInOut digitalInOut_(p20, PIN_INPUT, PullUp, 1); // TARGET_LPC1768 P1.31/SCK1/AD0.5
+    //
+    // these pins support PWM pwmDriver1 .. pwmDriver6
+    //DigitalInOut digitalInOut_(p21, PIN_INPUT, PullUp, 1); // TARGET_LPC1768 P2.5/PWM1.6/DTR1/TRACEDATA0
+    //DigitalInOut digitalInOut_(p22, PIN_INPUT, PullUp, 1); // TARGET_LPC1768 P2.4/PWM1.5/DSR1/TRACEDATA1
+    //DigitalInOut digitalInOut_(p23, PIN_INPUT, PullUp, 1); // TARGET_LPC1768 P2.3/PWM1.4/DCD1/TRACEDATA2
+    //DigitalInOut digitalInOut_(p24, PIN_INPUT, PullUp, 1); // TARGET_LPC1768 P2.2/PWM1.3/CTS1/TRACEDATA3
+    //DigitalInOut digitalInOut_(p25, PIN_INPUT, PullUp, 1); // TARGET_LPC1768 P2.1/PWM1.2/RXD1
+    //DigitalInOut digitalInOut_(p26, PIN_INPUT, PullUp, 1); // TARGET_LPC1768 P2.0/PWM1.1/TXD1/TRACECLK
+    //
+    // these could be additional digitalInOut pins
+#if HAS_digitalInOut10
+    DigitalInOut digitalInOut10(p27, PIN_INPUT, PullUp, 1); // TARGET_LPC1768 P0.11/RXD2/SCL2/MAT3.1
+#endif
+#if HAS_digitalInOut11
+    DigitalInOut digitalInOut11(p28, PIN_INPUT, PullUp, 1); // TARGET_LPC1768 P0.10/TXD2/SDA2/MAT3.0
+#endif
+#if HAS_digitalInOut12
+    DigitalInOut digitalInOut12(p29, PIN_INPUT, PullUp, 1); // TARGET_LPC1768 P0.5/I2SRX_WS/CAN_TX2/CAP2.1
+#endif
+#if HAS_digitalInOut13
+    DigitalInOut digitalInOut13(p30, PIN_INPUT, PullUp, 1); // TARGET_LPC1768 P0.4/I2SRX_CLK/CAN_RX2/CAP2.0
+#endif
+#if HAS_digitalInOut14
+    DigitalInOut digitalInOut14(___, PIN_INPUT, PullUp, 1);
+#endif
+#if HAS_digitalInOut15
+    DigitalInOut digitalInOut15(___, PIN_INPUT, PullUp, 1);
+#endif
+#else
+    // unknown target
+#endif
+// uncrustify-0.66.1 *INDENT-ON*
+#if HAS_digitalInOut0 || HAS_digitalInOut1 \
+    || HAS_digitalInOut2 || HAS_digitalInOut3 \
+    || HAS_digitalInOut4 || HAS_digitalInOut5 \
+    || HAS_digitalInOut6 || HAS_digitalInOut7 \
+    || HAS_digitalInOut8 || HAS_digitalInOut9 \
+    || HAS_digitalInOut10 || HAS_digitalInOut11 \
+    || HAS_digitalInOut12 || HAS_digitalInOut13 \
+    || HAS_digitalInOut14 || HAS_digitalInOut15 \
+    || HAS_digitalInOut16 || HAS_digitalInOut17
+#define HAS_digitalInOuts 1
+#endif
+
+// uncrustify-0.66.1 *INDENT-OFF*
+//--------------------------------------------------
+// Declare the PwmOut driver
+// Optional PwmOut support. If there is only one it should be pwmDriver1.
+// P) PWM pin#, duty cycle
+#if defined(TARGET_MAX32630)
+//       +-------------[microUSB]-------------+
+//       | J1         MAX32630FTHR        J2  |
+//       | [ ] RST                    GND [ ] |
+//       | [ ] 3V3                    BAT+[ ] |
+//       | [ ] 1V8                  reset SW1 |
+//       | [ ] GND       J4               J3  |
+//       | [ ] AIN_0 1.2Vfs     (bat) SYS [ ] |
+//       | [ ] AIN_1 1.2Vfs           PWR [ ] |
+//       | [ ] AIN_2 1.2Vfs      +5V VBUS [ ] |
+//       | [ ] AIN_3 1.2Vfs   1-WIRE P4_0 [x] | pwm4
+//       | [ ] P5_7  SDA2        SRN P5_6 [x] | pwm5
+//       | [ ] P6_0  SCL2      SDIO3 P5_5 [x] | pwm6
+// pwm13 | [ ] P5_0  SCLK      SDIO2 P5_4 [x] | pwm7
+// pwm14 | [ ] P5_1  MOSI       SSEL P5_3 [x] | pwm8
+// pwm3  | [x] P5_2  MISO        RTS P3_3 [x] | pwm9
+// pwm2  | [x] P3_0  RX          CTS P3_2 [ ] | pwm10
+// pwm1  | [x] P3_1  TX          SCL P3_5 [ ] | pwm11
+//       | [ ] GND               SDA P3_4 [ ] | pwm12
+//       +------------------------------------+
+// MAX32630FTHR mbed PwmOut driver is limited to 32-bit counter value;
+// see pwmout_update function in mbed-os/targets/TARGET_Maxim/TARGET_MAX32630/pwmout_api.c
+//      int div = (obj->period * (SystemCoreClock / 1000000))/32;
+#if HAS_SPI
+// avoid resource conflict between P5_0, P5_1, P5_2 SPI and DigitalInOut
+    #define HAS_pwmDriver13 0 // P5_0 PT8  TARGET_MAX32630 J1.11 pass ok; conflict PT8 P3_0 P5_0
+    #define HAS_pwmDriver14 0 // P5_1 PT9  TARGET_MAX32630 J1.12 pass ok; conflict PT9 P3_1 P5_1
+    #define HAS_pwmDriver3 0  // P5_2 PT10 TARGET_MAX32630 J1.13 pass ok; conflict PT10 P3_2 P5_2
+    #define HAS_pwmDriver2 0  // P3_0 PT8  TARGET_MAX32630 J1.14 pass ok; conflict PT8 P3_0 P5_0
+#endif
+//    #define HAS_pwmDriver0 0 // not assigned
+# ifndef HAS_pwmDriver1
+    //~ #define HAS_pwmDriver1 1 // P3_1 PT9  TARGET_MAX32630 J1.15 pass ok; conflict PT9 P3_1 P5_1
+# endif
+# ifndef HAS_pwmDriver2
+    #define HAS_pwmDriver2 1 // P3_0 PT8  TARGET_MAX32630 J1.14 pass ok; conflict PT8 P3_0 P5_0
+# endif
+# ifndef HAS_pwmDriver3
+    #define HAS_pwmDriver3 1 // P5_2 PT10 TARGET_MAX32630 J1.13 pass ok; conflict PT10 P3_2 P5_2
+# endif
+# ifndef HAS_pwmDriver4
+    //~ #define HAS_pwmDriver4 1 // P4_0 PT0  TARGET_MAX32630 J3.4 pass ok
+# endif
+# ifndef HAS_pwmDriver5
+    //~ #define HAS_pwmDriver5 1 // P5_6 PT14 TARGET_MAX32630 J3.5 pass ok
+# endif
+# ifndef HAS_pwmDriver6
+    //~ #define HAS_pwmDriver6 1 // P5_5 PT13 TARGET_MAX32630 J3.6 pass ok; conflict PT13 P3_5 P5_5
+# endif
+# ifndef HAS_pwmDriver7
+    //~ #define HAS_pwmDriver7 1 // P5_4 PT12 TARGET_MAX32630 J3.7 pass ok; conflict PT12 P3_4 P5_4
+# endif
+# ifndef HAS_pwmDriver8
+    //~ #define HAS_pwmDriver8 1 // P5_3 PT11 TARGET_MAX32630 J3.8 pass ok; conflict PT11 P3_3 P5_3
+# endif
+# ifndef HAS_pwmDriver9
+//    #define HAS_pwmDriver9 1 // P3_3 PT11 TARGET_MAX32630 J3.9 pass ok; conflict PT11 P3_3 P5_3
+# endif
+# ifndef HAS_pwmDriver10
+//    #define HAS_pwmDriver10 1 // P3_2 PT10 TARGET_MAX32630 J3.10 pass ok; conflict PT10 P3_2 P5_2
+# endif
+# ifndef HAS_pwmDriver11
+//    #define HAS_pwmDriver11 1 // P3_5 PT13 TARGET_MAX32630 J3.11 pass ok; conflict PT13 P3_5 P5_5
+# endif
+# ifndef HAS_pwmDriver12
+//    #define HAS_pwmDriver12 1 // P3_4 PT12 TARGET_MAX32630 J3.12 pass ok; conflict PT12 P3_4 P5_4
+# endif
+# ifndef HAS_pwmDriver13
+//    #define HAS_pwmDriver13 1 // P5_0 PT8  TARGET_MAX32630 J1.11 pass ok; conflict PT8 P3_0 P5_0
+# endif
+# ifndef HAS_pwmDriver14
+//    #define HAS_pwmDriver14 1 // P5_1 PT9  TARGET_MAX32630 J1.12 pass ok; conflict PT9 P3_1 P5_1
+# endif
+# ifndef HAS_pwmDriver15
+//    #define HAS_pwmDriver15 0 // not assigned
+# endif
+#if HAS_pwmDriver0
+    PwmOut pwmDriver0(____); // not assigned
+#endif
+#if HAS_pwmDriver1
+    PwmOut pwmDriver1(P3_1); // PT9  TARGET_MAX32630 J1.15 pass ok
+// Investigating which TARGET_MAX32630 PWM drivers work.
+// fail assert = runtime failure at system boot, as the only pwm pin
+// pass? = no runtime failure as the only pwm pin, may be ok
+// pass ok = plays well with others
+// PT0..PT15 identify which Pulse Train resource drives that GPIO pin
+    //PwmOut pwmDriver1(P5_7); // P5_7 PT15 TARGET_MAX32630 J1.9 fail assert; resource conflict
+    //PwmOut pwmDriver1(P6_0); // P6_0 PT0  TARGET_MAX32630 J1.10 fail assert; resource conflict
+    //PwmOut pwmDriver1(P5_0); // P5_0 PT8  TARGET_MAX32630 J1.11 pass ok; conflict PT8 P3_0 P5_0
+    //PwmOut pwmDriver1(P5_1); // P5_1 PT9  TARGET_MAX32630 J1.12 pass ok; conflict PT9 P3_1 P5_1
+    //PwmOut pwmDriver1(P5_2); // P5_2 PT10 TARGET_MAX32630 J1.13 pass ok; conflict PT10 P3_2 P5_2
+    //PwmOut pwmDriver1(P3_0); // P3_0 PT8  TARGET_MAX32630 J1.14 pass ok; conflict PT8 P3_0 P5_0
+    //PwmOut pwmDriver1(P3_1); // P3_1 PT9  TARGET_MAX32630 J1.15 pass ok; conflict PT9 P3_1 P5_1
+    //
+    //PwmOut pwmDriver1(P4_0); // P4_0 PT0  TARGET_MAX32630 J3.4 pass ok
+    //PwmOut pwmDriver1(P5_6); // P5_6 PT14 TARGET_MAX32630 J3.5 pass ok
+    //PwmOut pwmDriver1(P5_5); // P5_5 PT13 TARGET_MAX32630 J3.6 pass ok; conflict PT13 P3_5 P5_5
+    //PwmOut pwmDriver1(P5_4); // P5_4 PT12 TARGET_MAX32630 J3.7 pass ok; conflict PT12 P3_4 P5_4
+    //PwmOut pwmDriver1(P5_3); // P5_3 PT11 TARGET_MAX32630 J3.8 pass ok; conflict PT11 P3_3 P5_3
+    //PwmOut pwmDriver1(P3_3); // P3_3 PT11 TARGET_MAX32630 J3.9 pass ok; conflict PT11 P3_3 P5_3
+    //PwmOut pwmDriver1(P3_2); // P3_2 PT10 TARGET_MAX32630 J3.10 pass ok; conflict PT10 P3_2 P5_2
+    //PwmOut pwmDriver1(P3_5); // P3_5 PT13 TARGET_MAX32630 J3.11 pass ok; conflict PT13 P3_5 P5_5
+    //PwmOut pwmDriver1(P3_4); // P3_4 PT12 TARGET_MAX32630 J3.12 pass ok; conflict PT12 P3_4 P5_4
+#endif
+#if HAS_pwmDriver2
+    PwmOut pwmDriver2(P3_0); // P3_0 PT8  TARGET_MAX32630 J1.14 pass ok; conflict PT8 P3_0 P5_0
+#endif
+#if HAS_pwmDriver3
+    PwmOut pwmDriver3(P5_2); // P5_2 PT10 TARGET_MAX32630 J1.13 pass ok; conflict PT10 P3_2 P5_2
+#endif
+#if HAS_pwmDriver4
+    PwmOut pwmDriver4(P4_0); // P4_0 PT0  TARGET_MAX32630 J3.4 pass ok
+#endif
+#if HAS_pwmDriver5
+    PwmOut pwmDriver5(P5_6); // P5_6 PT14 TARGET_MAX32630 J3.5 pass ok
+#endif
+#if HAS_pwmDriver6
+    PwmOut pwmDriver6(P5_5); // P5_5 PT13 TARGET_MAX32630 J3.6 pass ok; conflict PT13 P3_5 P5_5
+#endif
+#if HAS_pwmDriver7
+    PwmOut pwmDriver7(P5_4); // P5_4 PT12 TARGET_MAX32630 J3.7 pass ok; conflict PT12 P3_4 P5_4
+#endif
+#if HAS_pwmDriver8
+    PwmOut pwmDriver8(P5_3); // P5_3 PT11 TARGET_MAX32630 J3.8 pass ok; conflict PT11 P3_3 P5_3
+#endif
+#if HAS_pwmDriver9
+    PwmOut pwmDriver9(P3_3); // P3_3 PT11 TARGET_MAX32630 J3.9 pass ok; conflict PT11 P3_3 P5_3
+#endif
+#if HAS_pwmDriver10
+    PwmOut pwmDriver10(P3_2); // P3_2 PT10 TARGET_MAX32630 J3.10 pass ok; conflict PT10 P3_2 P5_2
+#endif
+#if HAS_pwmDriver11
+    PwmOut pwmDriver11(P3_5); // P3_5 PT13 TARGET_MAX32630 J3.11 pass ok; conflict PT13 P3_5 P5_5
+#endif
+#if HAS_pwmDriver12
+    PwmOut pwmDriver12(P3_4); // P3_4 PT12 TARGET_MAX32630 J3.12 pass ok; conflict PT12 P3_4 P5_4
+#endif
+#if HAS_pwmDriver13
+    PwmOut pwmDriver13(P5_0); // P5_0 PT8  TARGET_MAX32630 J1.11 pass ok; conflict PT8 P3_0 P5_0
+#endif
+#if HAS_pwmDriver14
+    PwmOut pwmDriver14(P5_1); // P5_1 PT9  TARGET_MAX32630 J1.12 pass ok; conflict PT9 P3_1 P5_1
+#endif
+#if HAS_pwmDriver15
+    PwmOut pwmDriver15(____); // not assigned
+#endif
+//--------------------------------------------------
+#elif defined(TARGET_MAX32625MBED)
+//--------------------------------------------------
+// TODO1: pwmDriver TARGET=MAX32625MBED ARM Cortex-M4F 96MHz 512kB Flash 160kB SRAM
+#elif defined(TARGET_LPC1768)
+// TARGET=LPC1768 ARM Cortex-M3 100 MHz 512kB flash 64kB SRAM
+//               +-------------[microUSB]-------------+
+//        ______ | [ ] GND             +3.3V VOUT [ ] |
+//        ______ | [ ] 4.5V<VIN<9.0V   +5.0V VU   [ ] |
+//        ______ | [ ] VB                 USB.IF- [ ] |
+//        ______ | [ ] nR                 USB.IF+ [ ] |
+//        ______ | [ ] p5 MOSI       ETHERNET.RD- [ ] |
+//        ______ | [ ] p6 MISO       ETHERNET.RD+ [ ] |
+//        ______ | [ ] p7 SCLK       ETHERNET.TD- [ ] |
+//        ______ | [ ] p8            ETHERNET.TD+ [ ] |
+//        ______ | [ ] p9  TX SDA          USB.D- [ ] |
+//        ______ | [ ] p10 RX SCL          USB.D+ [ ] |
+//        ______ | [ ] p11    MOSI     CAN-RD p30 [ ] |
+//        ______ | [ ] p12    MISO     CAN-TD p29 [ ] |
+//        ______ | [ ] p13 TX SCLK     SDA TX p28 [ ] |
+//        ______ | [ ] p14 RX          SCL RX p27 [ ] |
+//        ______ | [ ] p15 AIN0 3.3Vfs   PWM1 p26 [ ] | pwmDriver1
+//        ______ | [ ] p16 AIN1 3.3Vfs   PWM2 p25 [ ] | pwmDriver2
+//        ______ | [ ] p17 AIN2 3.3Vfs   PWM3 p24 [ ] | pwmDriver3
+//        ______ | [ ] p18 AIN3 AOUT     PWM4 p23 [ ] | pwmDriver4
+//        ______ | [ ] p19 AIN4 3.3Vfs   PWM5 p22 [ ] | pwmDriver5
+//        ______ | [ ] p20 AIN5 3.3Vfs   PWM6 p21 [ ] | pwmDriver6
+//               +------------------------------------+
+//    #define HAS_pwmDriver0 1
+# ifndef HAS_pwmDriver1
+    #define HAS_pwmDriver1 1
+# endif
+# ifndef HAS_pwmDriver2
+    #define HAS_pwmDriver2 1
+# endif
+# ifndef HAS_pwmDriver3
+    #define HAS_pwmDriver3 1
+# endif
+# ifndef HAS_pwmDriver4
+    #define HAS_pwmDriver4 1
+# endif
+# ifndef HAS_pwmDriver5
+    #define HAS_pwmDriver5 1
+# endif
+# ifndef HAS_pwmDriver6
+    #define HAS_pwmDriver6 1
+# endif
+# ifndef HAS_pwmDriver7
+//    #define HAS_pwmDriver7 1
+# endif
+# ifndef HAS_pwmDriver8
+//    #define HAS_pwmDriver8 1
+# endif
+# ifndef HAS_pwmDriver9
+//    #define HAS_pwmDriver9 1
+# endif
+# ifndef HAS_pwmDriver10
+//    #define HAS_pwmDriver10 1
+# endif
+# ifndef HAS_pwmDriver11
+//    #define HAS_pwmDriver11 1
+# endif
+# ifndef HAS_pwmDriver12
+//    #define HAS_pwmDriver12 1
+# endif
+# ifndef HAS_pwmDriver13
+//    #define HAS_pwmDriver13 1
+# endif
+# ifndef HAS_pwmDriver14
+//    #define HAS_pwmDriver14 1
+# endif
+# ifndef HAS_pwmDriver15
+//    #define HAS_pwmDriver15 1
+# endif
+#if HAS_pwmDriver0
+    PwmOut pwmDriver0(____); // not assigned
+#endif
+#if HAS_pwmDriver1
+    PwmOut pwmDriver1(p26); // TARGET_LPC1768 P2.0/PWM1.1/TXD1/TRACECLK
+#endif
+#if HAS_pwmDriver2
+    PwmOut pwmDriver2(p25); // TARGET_LPC1768 P2.1/PWM1.2/RXD1
+#endif
+#if HAS_pwmDriver3
+    PwmOut pwmDriver3(p24); // TARGET_LPC1768 P2.2/PWM1.3/CTS1/TRACEDATA3
+#endif
+#if HAS_pwmDriver4
+    PwmOut pwmDriver4(p23); // TARGET_LPC1768 P2.3/PWM1.4/DCD1/TRACEDATA2
+#endif
+#if HAS_pwmDriver5
+    PwmOut pwmDriver5(p22); // TARGET_LPC1768 P2.4/PWM1.5/DSR1/TRACEDATA1
+#endif
+#if HAS_pwmDriver6
+    PwmOut pwmDriver6(p21); // TARGET_LPC1768 P2.5/PWM1.6/DTR1/TRACEDATA0
+#endif
+#if HAS_pwmDriver7
+    PwmOut pwmDriver7(____); // not assigned
+#endif
+#if HAS_pwmDriver8
+    PwmOut pwmDriver8(____); // not assigned
+#endif
+#if HAS_pwmDriver9
+    PwmOut pwmDriver9(____); // not assigned
+#endif
+#if HAS_pwmDriver10
+    PwmOut pwmDriver10(____); // not assigned
+#endif
+#if HAS_pwmDriver11
+    PwmOut pwmDriver11(____); // not assigned
+#endif
+#if HAS_pwmDriver12
+    PwmOut pwmDriver12(____); // not assigned
+#endif
+#if HAS_pwmDriver13
+    PwmOut pwmDriver13(____); // not assigned
+#endif
+#if HAS_pwmDriver14
+    PwmOut pwmDriver14(____); // not assigned
+#endif
+#if HAS_pwmDriver15
+    PwmOut pwmDriver15(____); // not assigned
+#endif
+#else
+    // unknown target
+#endif
+// uncrustify-0.66.1 *INDENT-ON*
+#if HAS_pwmDriver0 || HAS_pwmDriver1 \
+    || HAS_pwmDriver2 || HAS_pwmDriver3 \
+    || HAS_pwmDriver4 || HAS_pwmDriver5 \
+    || HAS_pwmDriver6 || HAS_pwmDriver7 \
+    || HAS_pwmDriver8 || HAS_pwmDriver9 \
+    || HAS_pwmDriver10 || HAS_pwmDriver11 \
+    || HAS_pwmDriver12 || HAS_pwmDriver13 \
+    || HAS_pwmDriver14 || HAS_pwmDriver15
+#define HAS_pwmDrivers 1
+#endif
+
+// uncrustify-0.66.1 *INDENT-OFF*
+//--------------------------------------------------
+// Declare the AnalogIn driver
+// Optional analogIn support. If there is only one it should be analogIn1.
+// A) analog input
+#if defined(TARGET_MAX32630)
+    #define HAS_analogIn0 1
+    #define HAS_analogIn1 1
+    #define HAS_analogIn2 1
+    #define HAS_analogIn3 1
+    #define HAS_analogIn4 1
+    #define HAS_analogIn5 1
+    #define HAS_analogIn6 1
+    #define HAS_analogIn7 1
+    #define HAS_analogIn8 1
+    #define HAS_analogIn9 1
+//    #define HAS_analogIn10 0
+//    #define HAS_analogIn11 0
+//    #define HAS_analogIn12 0
+//    #define HAS_analogIn13 0
+//    #define HAS_analogIn14 0
+//    #define HAS_analogIn15 0
+#if HAS_analogIn0
+    AnalogIn analogIn0(AIN_0); // TARGET_MAX32630 J1.5 AIN_0 = AIN0 pin       fullscale is 1.2V
+#endif
+#if HAS_analogIn1
+    AnalogIn analogIn1(AIN_1); // TARGET_MAX32630 J1.6 AIN_1 = AIN1 pin       fullscale is 1.2V
+#endif
+#if HAS_analogIn2
+    AnalogIn analogIn2(AIN_2); // TARGET_MAX32630 J1.7 AIN_2 = AIN2 pin       fullscale is 1.2V
+#endif
+#if HAS_analogIn3
+    AnalogIn analogIn3(AIN_3); // TARGET_MAX32630 J1.8 AIN_3 = AIN3 pin       fullscale is 1.2V
+#endif
+#if HAS_analogIn4
+    AnalogIn analogIn4(AIN_4); // TARGET_MAX32630 J1.5 AIN_4 = AIN0 / 5.0     fullscale is 6.0V
+#endif
+#if HAS_analogIn5
+    AnalogIn analogIn5(AIN_5); // TARGET_MAX32630 J1.6 AIN_5 = AIN1 / 5.0     fullscale is 6.0V
+#endif
+#if HAS_analogIn6
+    AnalogIn analogIn6(AIN_6); // TARGET_MAX32630 AIN_6 = VDDB / 4.0     fullscale is 4.8V
+#endif
+#if HAS_analogIn7
+    AnalogIn analogIn7(AIN_7); // TARGET_MAX32630 AIN_7 = VDD18          fullscale is 1.2V
+#endif
+#if HAS_analogIn8
+    AnalogIn analogIn8(AIN_8); // TARGET_MAX32630 AIN_8 = VDD12          fullscale is 1.2V
+#endif
+#if HAS_analogIn9
+    AnalogIn analogIn9(AIN_9); // TARGET_MAX32630 AIN_9 = VRTC / 2.0     fullscale is 2.4V
+#endif
+#if HAS_analogIn10
+    AnalogIn analogIn10(____); // TARGET_MAX32630 AIN_10 = x undefined?
+#endif
+#if HAS_analogIn11
+    AnalogIn analogIn11(____); // TARGET_MAX32630 AIN_11 = VDDIO / 4.0   fullscale is 4.8V
+#endif
+#if HAS_analogIn12
+    AnalogIn analogIn12(____); // TARGET_MAX32630 AIN_12 = VDDIOH / 4.0  fullscale is 4.8V
+#endif
+#if HAS_analogIn13
+    AnalogIn analogIn13(____);
+#endif
+#if HAS_analogIn14
+    AnalogIn analogIn14(____);
+#endif
+#if HAS_analogIn15
+    AnalogIn analogIn15(____);
+#endif
+//--------------------------------------------------
+#elif defined(TARGET_MAX32625MBED)
+    #define HAS_analogIn0 1
+    #define HAS_analogIn1 1
+    #define HAS_analogIn2 1
+    #define HAS_analogIn3 1
+    #define HAS_analogIn4 1
+    #define HAS_analogIn5 1
+#if HAS_analogIn0
+    AnalogIn analogIn0(AIN_0); // TARGET_MAX32630 J1.5 AIN_0 = AIN0 pin       fullscale is 1.2V
+#endif
+#if HAS_analogIn1
+    AnalogIn analogIn1(AIN_1); // TARGET_MAX32630 J1.6 AIN_1 = AIN1 pin       fullscale is 1.2V
+#endif
+#if HAS_analogIn2
+    AnalogIn analogIn2(AIN_2); // TARGET_MAX32630 J1.7 AIN_2 = AIN2 pin       fullscale is 1.2V
+#endif
+#if HAS_analogIn3
+    AnalogIn analogIn3(AIN_3); // TARGET_MAX32630 J1.8 AIN_3 = AIN3 pin       fullscale is 1.2V
+#endif
+#if HAS_analogIn4
+    AnalogIn analogIn4(AIN_4); // TARGET_MAX32630 J1.5 AIN_4 = AIN0 / 5.0     fullscale is 6.0V
+#endif
+#if HAS_analogIn5
+    AnalogIn analogIn5(AIN_5); // TARGET_MAX32630 J1.6 AIN_5 = AIN1 / 5.0     fullscale is 6.0V
+#endif
+//--------------------------------------------------
+#elif defined(TARGET_NUCLEO_F446RE)
+    #define HAS_analogIn0 1
+    #define HAS_analogIn1 1
+    #define HAS_analogIn2 1
+    #define HAS_analogIn3 1
+    #define HAS_analogIn4 1
+    #define HAS_analogIn5 1
+#if HAS_analogIn0
+    AnalogIn analogIn0(A0);
+#endif
+#if HAS_analogIn1
+    AnalogIn analogIn1(A1);
+#endif
+#if HAS_analogIn2
+    AnalogIn analogIn2(A2);
+#endif
+#if HAS_analogIn3
+    AnalogIn analogIn3(A3);
+#endif
+#if HAS_analogIn4
+    AnalogIn analogIn4(A4);
+#endif
+#if HAS_analogIn5
+    AnalogIn analogIn5(A5);
+#endif
+//--------------------------------------------------
+#elif defined(TARGET_NUCLEO_F401RE)
+    #define HAS_analogIn0 1
+    #define HAS_analogIn1 1
+    #define HAS_analogIn2 1
+    #define HAS_analogIn3 1
+    #define HAS_analogIn4 1
+    #define HAS_analogIn5 1
+#if HAS_analogIn0
+    AnalogIn analogIn0(A0);
+#endif
+#if HAS_analogIn1
+    AnalogIn analogIn1(A1);
+#endif
+#if HAS_analogIn2
+    AnalogIn analogIn2(A2);
+#endif
+#if HAS_analogIn3
+    AnalogIn analogIn3(A3);
+#endif
+#if HAS_analogIn4
+    AnalogIn analogIn4(A4);
+#endif
+#if HAS_analogIn5
+    AnalogIn analogIn5(A5);
+#endif
+//--------------------------------------------------
+// TODO1: TARGET=MAX32625MBED ARM Cortex-M4F 96MHz 512kB Flash 160kB SRAM
+#elif defined(TARGET_LPC1768)
+    #define HAS_analogIn0 1
+    #define HAS_analogIn1 1
+    #define HAS_analogIn2 1
+    #define HAS_analogIn3 1
+    #define HAS_analogIn4 1
+    #define HAS_analogIn5 1
+//    #define HAS_analogIn6 1
+//    #define HAS_analogIn7 1
+//    #define HAS_analogIn8 1
+//    #define HAS_analogIn9 1
+//    #define HAS_analogIn10 1
+//    #define HAS_analogIn11 1
+//    #define HAS_analogIn12 1
+//    #define HAS_analogIn13 1
+//    #define HAS_analogIn14 1
+//    #define HAS_analogIn15 1
+#if HAS_analogIn0
+    AnalogIn analogIn0(p15); // TARGET_LPC1768 P0.23/AD0.0/I2SRX_CLK/CAP3.0
+#endif
+#if HAS_analogIn1
+    AnalogIn analogIn1(p16); // TARGET_LPC1768 P0.24/AD0.1/I2SRX_WS/CAP3.1
+#endif
+#if HAS_analogIn2
+    AnalogIn analogIn2(p17); // TARGET_LPC1768 P0.25/AD0.2/I2SRX_SDA/TXD3
+#endif
+#if HAS_analogIn3
+    AnalogIn analogIn3(p18); // TARGET_LPC1768 P0.26/AD0.3/AOUT/RXD3
+#endif
+#if HAS_analogIn4
+    AnalogIn analogIn4(p19); // TARGET_LPC1768 P1.30/VBUS/AD0.4
+#endif
+#if HAS_analogIn5
+    AnalogIn analogIn5(p20); // TARGET_LPC1768 P1.31/SCK1/AD0.5
+#endif
+#if HAS_analogIn6
+    AnalogIn analogIn6(____);
+#endif
+#if HAS_analogIn7
+    AnalogIn analogIn7(____);
+#endif
+#if HAS_analogIn8
+    AnalogIn analogIn8(____);
+#endif
+#if HAS_analogIn9
+    AnalogIn analogIn9(____);
+#endif
+#if HAS_analogIn10
+    AnalogIn analogIn10(____);
+#endif
+#if HAS_analogIn11
+    AnalogIn analogIn11(____);
+#endif
+#if HAS_analogIn12
+    AnalogIn analogIn12(____);
+#endif
+#if HAS_analogIn13
+    AnalogIn analogIn13(____);
+#endif
+#if HAS_analogIn14
+    AnalogIn analogIn14(____);
+#endif
+#if HAS_analogIn15
+    AnalogIn analogIn15(____);
+#endif
+#else
+    // unknown target
+#endif
+// uncrustify-0.66.1 *INDENT-ON*
+#if HAS_analogIn0 || HAS_analogIn1 \
+    || HAS_analogIn2 || HAS_analogIn3 \
+    || HAS_analogIn4 || HAS_analogIn5 \
+    || HAS_analogIn6 || HAS_analogIn7 \
+    || HAS_analogIn8 || HAS_analogIn9 \
+    || HAS_analogIn10 || HAS_analogIn11 \
+    || HAS_analogIn12 || HAS_analogIn13 \
+    || HAS_analogIn14 || HAS_analogIn15
+#define HAS_analogIns 1
+#endif
+
+//--------------------------------------------------
+// Diagnostic: scope trigger
+//#define SCOPE_TRIG_PIN p11
+//#ifdef SCOPE_TRIG_PIN
+//# if defined(TARGET_MAX32630)
+//    // TARGET=MAX32630
+//    DigitalOut scopeTrigPinP11(P3_1, 1);
+//    DigitalOut scopePinP12(P3_0, 1);
+//# elif defined(TARGET_LPC1768)
+//    // TARGET=LPC1768
+//    DigitalOut scopeTrigPinP11(p11, 1);
+//    DigitalOut scopePinP12(p12, 1);
+//# else
+//    // unknown target
+//# endif
+//#endif
+
+//--------------------------------------------------
+// Option to use LEDs to show status
+#ifndef USE_LEDS
+#define USE_LEDS 1
+#endif
+#if USE_LEDS
+#if defined(TARGET_MAX32630)
+# define LED_ON  0
+# define LED_OFF 1
+//--------------------------------------------------
+#elif defined(TARGET_MAX32625MBED)
+# define LED_ON  0
+# define LED_OFF 1
+//--------------------------------------------------
+// TODO1: TARGET=MAX32625MBED ARM Cortex-M4F 96MHz 512kB Flash 160kB SRAM
+#elif defined(TARGET_LPC1768)
+# define LED_ON  1
+# define LED_OFF 0
+#else // not defined(TARGET_LPC1768 etc.)
+# define LED_ON  1
+# define LED_OFF 0
+#endif // target definition
+DigitalOut led1(LED1, LED_OFF); // MAX32630FTHR: LED1 = LED_RED
+DigitalOut led2(LED2, LED_OFF); // MAX32630FTHR: LED2 = LED_GREEN
+DigitalOut led3(LED3, LED_OFF); // MAX32630FTHR: LED3 = LED_BLUE
+DigitalOut led4(LED4, LED_OFF);
+#endif // USE_LEDS
+
+//--------------------------------------------------
+#if USE_LEDS
+class RGB_LED {
+public:
+    RGB_LED(DigitalOut &led_red, DigitalOut &led_green, DigitalOut &led_blue)
+        : m_red(led_red), m_green(led_green), m_blue(led_blue)
+    {
+    };
+    DigitalOut &m_red;
+    DigitalOut &m_green;
+    DigitalOut &m_blue;
+    ~RGB_LED()
+    {
+    };
+    /* diagnostic rbg led RED
+     */
+    void red() {
+        m_red = LED_ON; m_green = LED_OFF; m_blue = LED_OFF; // diagnostic rbg led RED
+    };
+    /* diagnostic rbg led GREEN
+     */
+    void green() {
+        m_red = LED_OFF; m_green = LED_ON; m_blue = LED_OFF; // diagnostic rbg led GREEN
+    };
+    /* diagnostic rbg led BLUE
+     */
+    void blue() {
+        m_red = LED_OFF; m_green = LED_OFF; m_blue = LED_ON; // diagnostic rbg led BLUE
+    };
+    /* diagnostic rbg led RED+GREEN+BLUE=WHITE
+     */
+    void white() {
+        m_red = LED_ON; m_green = LED_ON; m_blue = LED_ON; // diagnostic rbg led RED+GREEN+BLUE=WHITE
+    };
+    /* diagnostic rbg led GREEN+BLUE=CYAN
+     */
+    void cyan() {
+        m_red = LED_OFF; m_green = LED_ON; m_blue = LED_ON; // diagnostic rbg led GREEN+BLUE=CYAN
+    };
+    /* diagnostic rbg led RED+BLUE=MAGENTA
+     */
+    void magenta() {
+        m_red = LED_ON; m_green = LED_OFF; m_blue = LED_ON; // diagnostic rbg led RED+BLUE=MAGENTA
+    };
+    /* diagnostic rbg led RED+GREEN=YELLOW
+     */
+    void yellow() {
+        m_red = LED_ON; m_green = LED_ON; m_blue = LED_OFF; // diagnostic rbg led RED+GREEN=YELLOW
+    };
+    /* diagnostic rbg led BLACK
+     */
+    void black() {
+        m_red = LED_OFF; m_green = LED_OFF; m_blue = LED_OFF; // diagnostic rbg led BLACK
+    };
+};
+RGB_LED rgb_led(led1, led2, led3); // red, green, blue LEDs
+#endif // USE_LEDS
+
+//--------------------------------------------------
+// use BUTTON1 trigger some action
+#if defined(TARGET_MAX32630)
+#define HAS_BUTTON1_DEMO_INTERRUPT 1
+#elif defined(TARGET_MAX32625)
+#define HAS_BUTTON1_DEMO_INTERRUPT 1
+#define HAS_BUTTON2_DEMO_INTERRUPT 1
+#elif defined(TARGET_NUCLEO_F446RE)
+#define HAS_BUTTON1_DEMO_INTERRUPT 0
+#define HAS_BUTTON2_DEMO_INTERRUPT 0
+#elif defined(TARGET_NUCLEO_F401RE)
+#define HAS_BUTTON1_DEMO_INTERRUPT 0
+#define HAS_BUTTON2_DEMO_INTERRUPT 0
+#endif
+//
+#ifndef HAS_BUTTON1_DEMO
+#define HAS_BUTTON1_DEMO 0
+#endif
+#ifndef HAS_BUTTON2_DEMO
+#define HAS_BUTTON2_DEMO 0
+#endif
+//
+// avoid runtime error on button1 press [mbed-os-5.11]
+// instead of using InterruptIn, use DigitalIn and poll in main while(1)
+#ifndef HAS_BUTTON1_DEMO_INTERRUPT_POLLING
+#define HAS_BUTTON1_DEMO_INTERRUPT_POLLING 1
+#endif
+//
+#ifndef HAS_BUTTON1_DEMO_INTERRUPT
+#define HAS_BUTTON1_DEMO_INTERRUPT 1
+#endif
+#ifndef HAS_BUTTON2_DEMO_INTERRUPT
+#define HAS_BUTTON2_DEMO_INTERRUPT 1
+#endif
+//
+#if HAS_BUTTON1_DEMO_INTERRUPT
+# if HAS_BUTTON1_DEMO_INTERRUPT_POLLING
+// avoid runtime error on button1 press [mbed-os-5.11]
+// instead of using InterruptIn, use DigitalIn and poll in main while(1)
+DigitalIn button1(BUTTON1);
+# else
+InterruptIn button1(BUTTON1);
+# endif
+#elif HAS_BUTTON1_DEMO
+DigitalIn button1(BUTTON1);
+#endif
+#if HAS_BUTTON2_DEMO_INTERRUPT
+# if HAS_BUTTON1_DEMO_INTERRUPT_POLLING
+// avoid runtime error on button1 press [mbed-os-5.11]
+// instead of using InterruptIn, use DigitalIn and poll in main while(1)
+DigitalIn button2(BUTTON2);
+# else
+InterruptIn button2(BUTTON2);
+# endif
+#elif HAS_BUTTON2_DEMO
+DigitalIn button2(BUTTON2);
+#endif
+
+//--------------------------------------------------
+// Ticker is the periodic interrupt timer itself
+#define USE_PERIODIC_TIMER 0
+#if USE_PERIODIC_TIMER
+Ticker periodicInterruptTimer;
+us_timestamp_t periodicInterruptTimer_interval_usec = 50;
+us_timestamp_t periodicInterruptTimer_interval_usec_MAX = 1000;
+us_timestamp_t periodicInterruptTimer_interval_usec_MIN = 20;
+#endif
+
+
+#if APPLICATION_MAX5715 // hardware interface functions
+//----------------------------------------
+// User-provided hardware function
+// declare user-provided hardware interface function drive MAX5717_LDACb_Pin LDAC#
+// drive LDAC# Active-Low Asynchronous Load DAC Input for MAX5715
+//
+//void GPIOoutputLDACb(int isLogicHigh)
+//{
+//    digitalInOut9.output();
+//    digitalInOut9.write(isLogicHigh);
+//
+//#if HAS_MICROUSBSERIAL
+//    cmdLine_microUSBserial.serial().printf(" digitalInOutPin 9 Output %d ", isLogicHigh);
+//#endif
+//#if HAS_DAPLINK_SERIAL
+//    cmdLine_DAPLINKserial.serial().printf(" digitalInOutPin 9 Output %d ", isLogicHigh);
+//#endif
+//}
+
+//----------------------------------------
+// User-provided hardware function
+// declare user-provided hardware interface function drive MAX5717_CLRb_Pin CLR#
+// drive CLR# Active-Low Clear Input for MAX5715
+//
+//void GPIOoutputCLRb(int isLogicHigh)
+//{
+//    digitalInOut8.output();
+//    digitalInOut8.write(isLogicHigh);
+//
+//#if HAS_MICROUSBSERIAL
+//    cmdLine_microUSBserial.serial().printf(" digitalInOutPin 8 Output %d ", isLogicHigh);
+//#endif
+//#if HAS_DAPLINK_SERIAL
+//    cmdLine_DAPLINKserial.serial().printf(" digitalInOutPin 8 Output %d ", isLogicHigh);
+//#endif
+//}
+#endif
+
+
+#if APPLICATION_MAX11131 // hardware interface functions
+//----------------------------------------
+void print_value(CmdLine& cmdLine, int16_t value_u12, int channelId)
+{
+    int channelPairIndex = channelId / 2;
+    // format: 1 0 0 0 1 UCH0/1 UCH2/3 UCH4/5 UCH6/7 UCH8/9 UCH10/11 UCH12/13 UCH14/15 PDIFF_COM x x
+    // unused variable: int UCHn = (g_MAX11131_device.UNIPOLAR >> (10 - channelPairIndex)) & 0x01;
+    int BCHn = (g_MAX11131_device.BIPOLAR >> (10 - channelPairIndex)) & 0x01;
+    // unused variable: int RANGEn = (g_MAX11131_device.RANGE >> (10 - channelPairIndex)) & 0x01;
+    //
+    cmdLine.serial().printf(" ch=");
+    // TODO1: if CHANID=0 don't print ch=channelId
+    if ((g_MAX11131_device.isExternalClock == 0) || (g_MAX11131_device.chan_id_0_1 == 1))
+    {
+        // Internal clock modes always use channel ID.
+        // External clock modes use channel ID if ADC_MODE_CONTROL.CHAN_ID is 1.
+        cmdLine.serial().printf("%d", channelId);
+    } else {
+        cmdLine.serial().printf("?");
+    }
+    if (BCHn)
+    {
+        cmdLine.serial().printf(" xb=%d", g_MAX11131_device.TwosComplementValue(value_u12));
+    }
+    else
+    {
+        cmdLine.serial().printf(" xu=%d", value_u12);
+    }
+    cmdLine.serial().printf(" = 0x%4.4x = %6.4fV",
+                            (value_u12 & 0xFFFF),
+                            g_MAX11131_device.VoltageOfCode(value_u12, channelId)
+                            );
+    // dtostrf width and precision: 2.5v / 4096 LSB = 0.0006103515625 volts per LSB
+}
+
+//----------------------------------------
+// read data words
+// @pre RAW_misoData16[index] contains the raw SPI Master-In,Slave-Out data
+// @pre AINcode[NUM_CHANNELS] contains the latest readings in LSBs
+// For internal clock modes, the data format always includes the channel address.
+//     misoData16 = CH[3:0] DATA[11:0]
+void AINcode_print_value_chanID(CmdLine& cmdLine, int nWords)
+{
+    cmdLine.serial().printf("ScanRead_nWords_chanID nWords=%d\r\n", nWords);
+    for (int index = 0; index < nWords; index++) {
+        //~ int16_t misoData16 = MAX11131_ScanRead();
+        // For internal clock modes, the data format always includes the channel address.
+        //     misoData16 = CH[3:0] DATA[11:0]
+        int16_t value_u12 = (g_MAX11131_device.RAW_misoData16[index] & 0x0FFF);
+        int channelId = ((g_MAX11131_device.RAW_misoData16[index] >> 12) & 0x000F);
+        // diagnostic: print raw MISO data
+        cmdLine.serial().printf("      MAX11131.MISO[%u]=0x%4.4x:", index,
+                                (g_MAX11131_device.RAW_misoData16[index] & 0xFFFF));
+        print_value(cmdLine, value_u12, channelId);
+        cmdLine.serial().printf("\r\n");
+    }
+}
+
+//----------------------------------------
+// read data words
+// @pre RAW_misoData16[index] contains the raw SPI Master-In,Slave-Out data
+// @pre AINcode[NUM_CHANNELS] contains the latest readings in LSBs
+// For external clock modes, the data format returned depends on the CHAN_ID bit.
+//     when CHAN_ID = 0: misoData16 = 0 DATA[11:0] x x x
+//     when CHAN_ID = 1: misoData16 = CH[3:0] DATA[11:0]
+void AINcode_print_value_externalClock(CmdLine& cmdLine, int nWords)
+{
+    // For external clock modes, the data format returned depends on the CHAN_ID bit.
+    //     when CHAN_ID = 0: misoData16 = 0 DATA[11:0] x x x
+    //     when CHAN_ID = 1: misoData16 = CH[3:0] DATA[11:0]
+    // For internal clock modes, the data format always includes the channel address.
+    //     misoData16 = CH[3:0] DATA[11:0]
+    if (g_MAX11131_device.chan_id_0_1 != 0) {
+        AINcode_print_value_chanID(cmdLine, nWords);
+        return;
+    }
+    cmdLine.serial().printf("ScanRead_nWords_externalClock nWords=%d\r\n", nWords);
+    for (int index = 0; index < nWords; index++) {
+        // int16_t misoData16 = MAX11131_ScanRead();
+        int16_t value_u12 = ((g_MAX11131_device.RAW_misoData16[index] >> 3) & 0x0FFF);
+        int channelId = g_MAX11131_device.channelNumber_0_15;
+        // diagnostic: print raw MISO data
+        cmdLine.serial().printf("      MAX11131.MISO[%u]=0x%4.4x:", index,
+                                (g_MAX11131_device.RAW_misoData16[index] & 0xFFFF));
+        print_value(cmdLine, value_u12, channelId);
+        cmdLine.serial().printf("\r\n");
+    }
+}
+
+//----------------------------------------
+// read data words and calculate mean, stddev
+// @pre RAW_misoData16[index] contains the raw SPI Master-In,Slave-Out data
+// @pre AINcode[NUM_CHANNELS] contains the latest readings in LSBs
+void AINcode_print_value_chanID_mean(CmdLine& cmdLine, int nWords)
+{
+    cmdLine.serial().printf("ScanRead_nWords_chanID_mean nWords=%d\r\n", nWords);
+    double Sx = 0;
+    double Sxx = 0;
+    for (int index = 0; index < nWords; index++) {
+        //~ int16_t misoData16 = MAX11131_ScanRead();
+        // For internal clock modes, the data format always includes the channel address.
+        //     misoData16 = CH[3:0] DATA[11:0]
+        int16_t value_u12 = (g_MAX11131_device.RAW_misoData16[index] & 0x0FFF);
+        int channelId = ((g_MAX11131_device.RAW_misoData16[index] >> 12) & 0x000F);
+        // TODO: sign-extend value_s12 from value_u12
+        //
+        cmdLine.serial().printf("n=%d", index);
+        print_value(cmdLine, value_u12, channelId);
+        //
+        Sx = Sx + value_u12;
+        Sxx = Sxx + ((double)value_u12 * value_u12);
+        cmdLine.serial().printf(" Sx=%f Sxx=%f\r\n", Sx, Sxx);
+    }
+    double mean = Sx / nWords;
+    cmdLine.serial().printf("  mean=%f=0x%4.4x", mean, (int)mean);
+    // calculate standard deviation from N, Sx, Sxx
+    if (nWords >= 2)
+    {
+        double variance = (Sxx - ( Sx * Sx / nWords)) / (nWords - 1);
+        // stddev = square root of variance
+        double stddev = sqrt(variance);
+        cmdLine.serial().printf("  variance=%f  stddev=%f", variance, stddev);
+    }
+    cmdLine.serial().printf("\r\n");
+}
+
+/* MAX11131_print_register_verbose
+ *
+ * TODO: document this function
+ * This header was inserted by uncrustify; see uncrustify_func_header.txt.
+ *
+ */
+void MAX11131_print_register_verbose(CmdLine& cmdLine, int16_t registerData)
+{
+    if (registerData & 0x8000)
+    {
+        switch (registerData & 0xF800)
+        {
+            case 0x8000: // ADC_CONFIGURATION 0x8000..0x87FF format: 1 0 0 0 0 REFSEL AVGON NAVG[1:0] NSCAN[1:0] SPM[1:0] ECHO 0 0
+                cmdLine.serial().printf(" ADC_CONFIGURATION");
+                {
+                    // define write-only register ADC_CONFIGURATION
+                    //int16_t ADC_CONFIGURATION = 0x8000; //!< registerData 0x8000..0x87FF format: 1 0 0 0 0 REFSEL AVGON NAVG[1:0] NSCAN[1:0] SPM[1:0] ECHO 0 0
+                    const int REFSEL_LSB = 10; const int REFSEL_BITS = 0x01; // ADC_CONFIGURATION.REFSEL
+                    const int AVGON_LSB = 9; const int AVGON_BITS = 0x01; // ADC_CONFIGURATION.AVGON
+                    const int NAVG_LSB = 7; const int NAVG_BITS = 0x03; // ADC_CONFIGURATION.NAVG[1:0]
+                    const int NSCAN_LSB = 5; const int NSCAN_BITS = 0x03; // ADC_CONFIGURATION.NSCAN[1:0]
+                    const int SPM_LSB = 3; const int SPM_BITS = 0x03; // ADC_CONFIGURATION.SPM[1:0]
+                    const int ECHO_LSB = 2; const int ECHO_BITS = 0x01; // ADC_CONFIGURATION.ECHO
+
+                    const int REFSEL = ((registerData >> REFSEL_LSB) & REFSEL_BITS);
+                    const int AVGON = ((registerData >> AVGON_LSB) & AVGON_BITS);
+                    const int NAVG = ((registerData >> NAVG_LSB) & NAVG_BITS);
+                    const int NSCAN = ((registerData >> NSCAN_LSB) & NSCAN_BITS);
+                    const int SPM = ((registerData >> SPM_LSB) & SPM_BITS);
+                    const int ECHO = ((registerData >> ECHO_LSB) & ECHO_BITS);
+
+                    if (REFSEL) {
+                        cmdLine.serial().printf(" REFSEL=%d", REFSEL);
+                    }
+                    if (AVGON) {
+                        cmdLine.serial().printf(" AVGON=%d", AVGON);
+                    }
+                    if (NAVG) {
+                        cmdLine.serial().printf(" NAVG=%d", NAVG);
+                    }
+                    if (NSCAN) {
+                        cmdLine.serial().printf(" NSCAN=%d", NSCAN);
+                    }
+                    if (SPM) {
+                        cmdLine.serial().printf(" SPM=%d", SPM);
+                    }
+                    if (ECHO) {
+                        cmdLine.serial().printf(" ECHO=%d", ECHO);
+                    }
+                }
+                break;
+            case 0x8800: // UNIPOLAR 0x8800..0x8FFF format: 1 0 0 0 1 UCH0/1 UCH2/3 UCH4/5 UCH6/7 UCH8/9 UCH10/11 UCH12/13 UCH14/15 PDIFF_COM x x
+                cmdLine.serial().printf(" UNIPOLAR 0x%4.4x", ((registerData >> 3) & 0xFF));
+                if ((registerData >> 2) & 0x01) {
+                    cmdLine.serial().printf(" PDIFF_COM");
+                }
+                break;
+            case 0x9000: // BIPOLAR 0x9000..0x97FF format: 1 0 0 1 0 BCH0/1 BCH2/3 BCH4/5 BCH6/7 BCH8/9 BCH10/11 BCH12/13 BCH14/15 x x x
+                cmdLine.serial().printf(" BIPOLAR  0x%4.4x", ((registerData >> 3) & 0xFF));
+                break;
+            case 0x9800: // RANGE 0x9800..0x9FFF format: 1 0 0 1 1 RANGE0/1 RANGE2/3 RANGE4/5 RANGE6/7 RANGE8/9 RANGE10/11 RANGE12/13 RANGE14/15 x x x
+                cmdLine.serial().printf(" RANGE    0x%4.4x", ((registerData >> 3) & 0xFF));
+                break;
+            case 0xA000: // CSCAN0 0xA000..0xA7FF format: 1 0 1 0 0 CHSCAN15 CHSCAN14 CHSCAN13 CHSCAN12 CHSCAN11 CHSCAN10 CHSCAN9 CHSCAN8 x x x
+                cmdLine.serial().printf(" CSCAN0 0x%4.4x", ((registerData >> 3) & 0xFF));
+                break;
+            case 0xA800: // CSCAN1 0xA800..0xAFFF format: 1 0 1 0 1 CHSCAN7 CHSCAN6 CHSCAN5 CHSCAN4 CHSCAN3 CHSCAN2 CHSCAN1 CHSCAN0 x x x
+                cmdLine.serial().printf(" CSCAN1 0x%4.4x", ((registerData >> 3) & 0xFF));
+                break;
+            case 0xB000: // SAMPLESET 0xB000..0xB7FF format: 1 0 1 1 0 SEQ_LENGTH[7:0] x x x
+                cmdLine.serial().printf(" SAMPLESET SEQ_LENGTH[7:0]=0x%4.4x", ((registerData >> 3) & 0xFF));
+                cmdLine.serial().printf(" so length=%d channels", (((registerData >> 3) & 0xFF) + 1));
+                break;
+            default:
+                cmdLine.serial().printf(" ???");
+                break;
+        }
+    }
+    else
+    {
+        // ADC_MODE_CONTROL 0x0000..0x7FFF format: 0 SCAN[3:0] CHSEL[3:0] RESET[1:0] PM[1:0] CHAN_ID SWCNV 0
+        cmdLine.serial().printf(" ADC_MODE_CONTROL");
+
+        // define write-only register ADC_MODE_CONTROL
+        //int16_t ADC_MODE_CONTROL = 0;       //!< registerData 0x0000..0x7FFF format: 0 SCAN[3:0] CHSEL[3:0] RESET[1:0] PM[1:0] CHAN_ID SWCNV 0
+        const int SCAN_LSB = 11; const int SCAN_BITS = 0x0F;   //!< ADC_MODE_CONTROL.SCAN[3:0] ADC Scan Control (command)
+        const int CHSEL_LSB = 7; const int CHSEL_BITS = 0x0F;  //!< ADC_MODE_CONTROL.CHSEL[3:0] Analog Input Channel Select AIN0..AIN15
+        const int RESET_LSB = 5; const int RESET_BITS = 0x03;  //!< ADC_MODE_CONTROL.RESET[1:0] Reset 0=Normal 1=ResetFIFO 2=ResetAllRegisters 3=reserved
+        const int PM_LSB = 3; const int PM_BITS = 0x03;        //!< ADC_MODE_CONTROL.PM[1:0] Power Management 0=Normal, 1=AutoShutdown, 2=AutoStandby 3=reserved
+        const int CHAN_ID_LSB = 2; const int CHAN_ID_BITS = 0x01; //!< ADC_MODE_CONTROL.CHAN_ID
+        const int SWCNV_LSB = 1; const int SWCNV_BITS = 0x01;  //!< ADC_MODE_CONTROL.SWCNV
+
+        const int SCAN = ((registerData >> SCAN_LSB) & SCAN_BITS);
+        const int CHSEL = ((registerData >> CHSEL_LSB) & CHSEL_BITS);
+        const int RESET = ((registerData >> RESET_LSB) & RESET_BITS);
+        const int PM = ((registerData >> PM_LSB) & PM_BITS);
+        const int CHANID = ((registerData >> CHAN_ID_LSB) & CHAN_ID_BITS);
+        const int SWCNV = ((registerData >> SWCNV_LSB) & SWCNV_BITS);
+
+        switch (SCAN)
+        {
+            case MAX11131::SCAN_0000_NOP:
+                cmdLine.serial().printf(" SCAN_0000_NOP");
+                break;
+            case MAX11131::SCAN_0001_Manual:
+                cmdLine.serial().printf(" SCAN_0001_Manual CHSEL=%d", CHSEL);
+                break;
+            case MAX11131::SCAN_0010_Repeat:
+                cmdLine.serial().printf(" SCAN_0010_Repeat CHSEL=%d", CHSEL);
+                break;
+            case MAX11131::SCAN_0011_StandardInternalClock:
+                cmdLine.serial().printf(" SCAN_0011_StandardInt CHSEL=%d", CHSEL);
+                break;
+            case MAX11131::SCAN_0100_StandardExternalClock:
+                cmdLine.serial().printf(" SCAN_0100_StandardExt CHSEL=%d", CHSEL);
+                break;
+            case MAX11131::SCAN_0101_UpperInternalClock:
+                cmdLine.serial().printf(" SCAN_0101_UpperInt CHSEL=%d", CHSEL);
+                break;
+            case MAX11131::SCAN_0110_UpperExternalClock:
+                cmdLine.serial().printf(" SCAN_0110_UpperExt CHSEL=%d", CHSEL);
+                break;
+            case MAX11131::SCAN_0111_CustomInternalClock:
+                cmdLine.serial().printf(" SCAN_0111_CustomInt");
+                break;
+            case MAX11131::SCAN_1000_CustomExternalClock:
+                cmdLine.serial().printf(" SCAN_1000_CustomExt");
+                break;
+            case MAX11131::SCAN_1001_SampleSetExternalClock:
+                cmdLine.serial().printf(" SCAN_1001_SampleSetExt");
+                break;
+            default:
+                cmdLine.serial().printf(" SCAN=%d", SCAN);
+                cmdLine.serial().printf(" CHSEL=%d", CHSEL);
+        }
+        if (RESET) {
+            cmdLine.serial().printf(" RESET=%d", RESET);
+        }
+        if (PM) {
+            cmdLine.serial().printf(" PM=%d", PM);
+        }
+        if (SCAN != MAX11131::SCAN_0000_NOP)
+        {
+            if (g_MAX11131_device.isExternalClock)
+            {
+                // if external clock mode, print CHANID
+                cmdLine.serial().printf(" CHANID=%d", CHANID);
+            }
+            else
+            {
+                // if internal clock mode, print SWCNV
+                cmdLine.serial().printf(" SWCNV=%d", SWCNV);
+            }
+        }
+    }
+    cmdLine.serial().printf("\r\n");
+}
+
+//----------------------------------------
+// User-provided hardware function
+// declare user-provided hardware interface function
+// Assert CNVST convert start.
+// Required when using any of the InternalClock modes with SWCNV 0.
+// Trigger measurement by driving CNVST/AIN14 pin low for a minimum active-low pulse duration of 5ns. (AIN14 is not available)
+//
+//void CNVSToutputPulseLow()
+//{
+//    digitalInOut9.output();
+//    digitalInOut9.write(0);
+//    // CNVST active-low pulse duration must be 5ns (0.005us) minimum.
+//    digitalInOut9.write(1);
+//
+//#if HAS_MICROUSBSERIAL
+//    cmdLine_microUSBserial.serial().printf(" CNVSToutputPulseLow ");
+//#endif
+//#if HAS_DAPLINK_SERIAL
+//    cmdLine_DAPLINKserial.serial().printf(" CNVSToutputPulseLow ");
+//#endif
+//}
+
+//----------------------------------------
+// User-provided hardware function
+// declare user-provided hardware interface function
+// Wait for EOC pin low, indicating end of conversion.
+// Required when using any of the InternalClock modes.
+//
+//void EOCinputWaitUntilLow()
+//{
+//    //
+//    // Arduino: pulseIn(pinIndex, HIGH | LOW, timeout_usec) // length of pulse in usec, or 0 if timeout
+//    //
+//    // const int timeout_usec = 1000;
+//    // TODO1: implement EOCinputWaitUntilLow APPLICATION_MAX11131
+//    // similar to Arduino pulseIn(MAX11131_EOC_Pin, LOW, timeout_usec);
+//#if HAS_MICROUSBSERIAL
+//    cmdLine_microUSBserial.serial().printf(" EOCinputWaitUntilLow ");
+//#endif
+//#if HAS_DAPLINK_SERIAL
+//    cmdLine_DAPLINKserial.serial().printf(" EOCinputWaitUntilLow ");
+//#endif
+//}
+
+//----------------------------------------
+// User-provided hardware function
+// declare user-provided hardware interface function
+// Assert SPI Chip Select
+// SPI chip-select for MAX5715
+//
+//void SPIoutputCS(int isLogicHigh)
+//{
+//    g_SPI_cs_state = isLogicHigh;
+//    spi_cs = g_SPI_cs_state;
+//}
+
+//----------------------------------------
+// User-provided hardware function
+// declare user-provided hardware interface function SPI write 16 bits
+// SPI interface to MAX11131 shift 16 bits mosiData16 into MAX11131 DIN
+// ignoring MAX11131 DOUT
+//void SPIwrite16bits(int16_t mosiData16)
+//{
+//    // TODO1: implement SPIwrite16bits
+//    size_t byteCount = 2;
+//    static char mosiData[2];
+//    static char misoData[2];
+//    mosiData[0] = (char)((mosiData16 >> 8) & 0xFF); // MSByte
+//    mosiData[1] = (char)((mosiData16 >> 0) & 0xFF); // LSByte
+//    //
+//    // Arduino: begin critical section: noInterrupts() masks all interrupt sources; end critical section with interrupts()
+//    //~ noInterrupts();
+//    //
+//    //~ digitalWrite(Scope_Trigger_Pin, LOW); // diagnostic Scope_Trigger_Pin
+//    //
+//    unsigned int numBytesTransferred = spi.write(mosiData, byteCount, misoData, byteCount);
+//    //~ SPI.transfer(mosiData8_FF0000);
+//    //~ SPI.transfer(mosiData16_00FF00);
+//    //~ SPI.transfer(mosiData16_0000FF);
+//    //
+//    //~ digitalWrite(Scope_Trigger_Pin, HIGH); // diagnostic Scope_Trigger_Pin
+//    //
+//    // Arduino: begin critical section: noInterrupts() masks all interrupt sources; end critical section with interrupts()
+//    //~ interrupts();
+//    //
+//    // VERIFY: SPIwrite24bits print diagnostic information
+//    //cmdLine.serial().printf(" MOSI->"));
+//    //cmdLine.serial().printf(" 0x"));
+//    //Serial.print( (mosiData8_FF0000 & 0xFF), HEX);
+//    //cmdLine.serial().printf(" 0x"));
+//    //Serial.print( (mosiData16_00FF00 & 0xFF), HEX);
+//    //cmdLine.serial().printf(" 0x"));
+//    //Serial.print( (mosiData16_0000FF & 0xFF), HEX);
+//    // hex dump mosiData[0..byteCount-1]
+//#if HAS_MICROUSBSERIAL
+//    cmdLine_microUSBserial.serial().printf("\r\nSPI");
+//    if (byteCount > 7) {
+//        cmdLine_microUSBserial.serial().printf(" byteCount:%d", byteCount);
+//    }
+//    cmdLine_microUSBserial.serial().printf(" MOSI->");
+//    for (unsigned int byteIndex = 0; byteIndex < byteCount; byteIndex++)
+//    {
+//        cmdLine_microUSBserial.serial().printf(" 0x%2.2X", mosiData[byteIndex]);
+//    }
+//    // hex dump misoData[0..byteCount-1]
+//    cmdLine_microUSBserial.serial().printf("  MISO<-");
+//    for (unsigned int byteIndex = 0; byteIndex < numBytesTransferred; byteIndex++)
+//    {
+//        cmdLine_microUSBserial.serial().printf(" 0x%2.2X", misoData[byteIndex]);
+//    }
+//    cmdLine_microUSBserial.serial().printf(" ");
+//#endif
+//#if HAS_DAPLINK_SERIAL
+//    cmdLine_DAPLINKserial.serial().printf("\r\nSPI");
+//    if (byteCount > 7) {
+//        cmdLine_DAPLINKserial.serial().printf(" byteCount:%d", byteCount);
+//    }
+//    cmdLine_DAPLINKserial.serial().printf(" MOSI->");
+//    for (unsigned int byteIndex = 0; byteIndex < byteCount; byteIndex++)
+//    {
+//        cmdLine_DAPLINKserial.serial().printf(" 0x%2.2X", mosiData[byteIndex]);
+//    }
+//    // hex dump misoData[0..byteCount-1]
+//    cmdLine_DAPLINKserial.serial().printf("  MISO<-");
+//    for (unsigned int byteIndex = 0; byteIndex < numBytesTransferred; byteIndex++)
+//    {
+//        cmdLine_DAPLINKserial.serial().printf(" 0x%2.2X", misoData[byteIndex]);
+//    }
+//    cmdLine_DAPLINKserial.serial().printf(" ");
+//#endif
+//    // VERIFY: DIAGNOSTIC: print MAX5715 device register write
+//    // TODO: MAX5715_print_register_verbose(mosiData8_FF0000, mosiData16_00FFFF);
+//    // TODO: print_verbose_SPI_diagnostic(mosiData16_FF00, mosiData16_00FF, misoData16_FF00, misoData16_00FF);
+//    //
+//    // int misoData16 = (misoData16_FF00 << 8) | misoData16_00FF;
+//    // return misoData16;
+//}
+
+//----------------------------------------
+// User-provided hardware function
+// declare user-provided hardware interface function SPI write 17-24 bits
+// SPI interface to MAX11131 shift 16 bits mosiData16 into MAX11131 DIN
+// followed by one additional SCLK byte.
+// ignoring MAX11131 DOUT
+//void SPIwrite24bits(int16_t mosiData16_FFFF00, int8_t mosiData8_0000FF)
+//{
+//    // TODO1: implement SPIwrite24bits
+//    size_t byteCount = 3;
+//    static char mosiData[3];
+//    static char misoData[3];
+//    mosiData[0] = (char)((mosiData16_FFFF00 >> 8) & 0xFF); // MSByte
+//    mosiData[1] = (char)((mosiData16_FFFF00 >> 0) & 0xFF); // LSByte
+//    mosiData[2] = mosiData8_0000FF;
+//    //
+//    // Arduino: begin critical section: noInterrupts() masks all interrupt sources; end critical section with interrupts()
+//    //~ noInterrupts();
+//    //
+//    //~ digitalWrite(Scope_Trigger_Pin, LOW); // diagnostic Scope_Trigger_Pin
+//    //
+//    unsigned int numBytesTransferred = spi.write(mosiData, byteCount, misoData, byteCount);
+//    //~ SPI.transfer(mosiData8_FF0000);
+//    //~ SPI.transfer(mosiData16_00FF00);
+//    //~ SPI.transfer(mosiData16_0000FF);
+//    //
+//    //~ digitalWrite(Scope_Trigger_Pin, HIGH); // diagnostic Scope_Trigger_Pin
+//    //
+//    // Arduino: begin critical section: noInterrupts() masks all interrupt sources; end critical section with interrupts()
+//    //~ interrupts();
+//    //
+//    // VERIFY: SPIwrite24bits print diagnostic information
+//    //cmdLine.serial().printf(" MOSI->"));
+//    //cmdLine.serial().printf(" 0x"));
+//    //Serial.print( (mosiData8_FF0000 & 0xFF), HEX);
+//    //cmdLine.serial().printf(" 0x"));
+//    //Serial.print( (mosiData16_00FF00 & 0xFF), HEX);
+//    //cmdLine.serial().printf(" 0x"));
+//    //Serial.print( (mosiData16_0000FF & 0xFF), HEX);
+//    // hex dump mosiData[0..byteCount-1]
+//#if HAS_MICROUSBSERIAL
+//    cmdLine_microUSBserial.serial().printf("\r\nSPI");
+//    if (byteCount > 7) {
+//        cmdLine_microUSBserial.serial().printf(" byteCount:%d", byteCount);
+//    }
+//    cmdLine_microUSBserial.serial().printf(" MOSI->");
+//    for (unsigned int byteIndex = 0; byteIndex < byteCount; byteIndex++)
+//    {
+//        cmdLine_microUSBserial.serial().printf(" 0x%2.2X", mosiData[byteIndex]);
+//    }
+//    // hex dump misoData[0..byteCount-1]
+//    cmdLine_microUSBserial.serial().printf("  MISO<-");
+//    for (unsigned int byteIndex = 0; byteIndex < numBytesTransferred; byteIndex++)
+//    {
+//        cmdLine_microUSBserial.serial().printf(" 0x%2.2X", misoData[byteIndex]);
+//    }
+//    cmdLine_microUSBserial.serial().printf(" ");
+//#endif
+//#if HAS_DAPLINK_SERIAL
+//    cmdLine_DAPLINKserial.serial().printf("\r\nSPI");
+//    if (byteCount > 7) {
+//        cmdLine_DAPLINKserial.serial().printf(" byteCount:%d", byteCount);
+//    }
+//    cmdLine_DAPLINKserial.serial().printf(" MOSI->");
+//    for (unsigned int byteIndex = 0; byteIndex < byteCount; byteIndex++)
+//    {
+//        cmdLine_DAPLINKserial.serial().printf(" 0x%2.2X", mosiData[byteIndex]);
+//    }
+//    // hex dump misoData[0..byteCount-1]
+//    cmdLine_DAPLINKserial.serial().printf("  MISO<-");
+//    for (unsigned int byteIndex = 0; byteIndex < numBytesTransferred; byteIndex++)
+//    {
+//        cmdLine_DAPLINKserial.serial().printf(" 0x%2.2X", misoData[byteIndex]);
+//    }
+//    cmdLine_DAPLINKserial.serial().printf(" ");
+//#endif
+//    // VERIFY: DIAGNOSTIC: print MAX5715 device register write
+//    // TODO: MAX5715_print_register_verbose(mosiData8_FF0000, mosiData16_00FFFF);
+//    //
+//    // int misoData16 = (misoData16_FF00 << 8) | misoData16_00FF;
+//    // return misoData16;
+//}
+
+//----------------------------------------
+// User-provided hardware function
+// declare user-provided hardware interface function SPI read 16 bits while MOSI (Maxim DIN) is 0
+// SPI interface to capture 16 bits miso data from MAX11131 DOUT
+//int16_t SPIread16bits()
+//{
+//    // TODO1: implement SPIread16bits
+//    int mosiData16 = 0;
+//    size_t byteCount = 2;
+//    static char mosiData[2];
+//    static char misoData[2];
+//    mosiData[0] = (char)((mosiData16 >> 8) & 0xFF); // MSByte
+//    mosiData[1] = (char)((mosiData16 >> 0) & 0xFF); // LSByte
+//    //
+//    // Arduino: begin critical section: noInterrupts() masks all interrupt sources; end critical section with interrupts()
+//    //~ noInterrupts();
+//    //
+//    //~ digitalWrite(Scope_Trigger_Pin, LOW); // diagnostic Scope_Trigger_Pin
+//    //
+//    unsigned int numBytesTransferred = spi.write(mosiData, byteCount, misoData, byteCount);
+//    //~ SPI.transfer(mosiData8_FF0000);
+//    //~ SPI.transfer(mosiData16_00FF00);
+//    //~ SPI.transfer(mosiData16_0000FF);
+//    //
+//    //~ digitalWrite(Scope_Trigger_Pin, HIGH); // diagnostic Scope_Trigger_Pin
+//    //
+//    // Arduino: begin critical section: noInterrupts() masks all interrupt sources; end critical section with interrupts()
+//    //~ interrupts();
+//    //
+//    // VERIFY: SPIwrite24bits print diagnostic information
+//    //cmdLine.serial().printf(" MOSI->"));
+//    //cmdLine.serial().printf(" 0x"));
+//    //Serial.print( (mosiData8_FF0000 & 0xFF), HEX);
+//    //cmdLine.serial().printf(" 0x"));
+//    //Serial.print( (mosiData16_00FF00 & 0xFF), HEX);
+//    //cmdLine.serial().printf(" 0x"));
+//    //Serial.print( (mosiData16_0000FF & 0xFF), HEX);
+//    // hex dump mosiData[0..byteCount-1]
+//#if HAS_MICROUSBSERIAL
+//    cmdLine_microUSBserial.serial().printf("\r\nSPI");
+//    if (byteCount > 7) {
+//        cmdLine_microUSBserial.serial().printf(" byteCount:%d", byteCount);
+//    }
+//    cmdLine_microUSBserial.serial().printf(" MOSI->");
+//    for (unsigned int byteIndex = 0; byteIndex < byteCount; byteIndex++)
+//    {
+//        cmdLine_microUSBserial.serial().printf(" 0x%2.2X", mosiData[byteIndex]);
+//    }
+//    // hex dump misoData[0..byteCount-1]
+//    cmdLine_microUSBserial.serial().printf("  MISO<-");
+//    for (unsigned int byteIndex = 0; byteIndex < numBytesTransferred; byteIndex++)
+//    {
+//        cmdLine_microUSBserial.serial().printf(" 0x%2.2X", misoData[byteIndex]);
+//    }
+//    cmdLine_microUSBserial.serial().printf(" ");
+//#endif
+//#if HAS_DAPLINK_SERIAL
+//    cmdLine_DAPLINKserial.serial().printf("\r\nSPI");
+//    if (byteCount > 7) {
+//        cmdLine_DAPLINKserial.serial().printf(" byteCount:%d", byteCount);
+//    }
+//    cmdLine_DAPLINKserial.serial().printf(" MOSI->");
+//    for (unsigned int byteIndex = 0; byteIndex < byteCount; byteIndex++)
+//    {
+//        cmdLine_DAPLINKserial.serial().printf(" 0x%2.2X", mosiData[byteIndex]);
+//    }
+//    // hex dump misoData[0..byteCount-1]
+//    cmdLine_DAPLINKserial.serial().printf("  MISO<-");
+//    for (unsigned int byteIndex = 0; byteIndex < numBytesTransferred; byteIndex++)
+//    {
+//        cmdLine_DAPLINKserial.serial().printf(" 0x%2.2X", misoData[byteIndex]);
+//    }
+//    cmdLine_DAPLINKserial.serial().printf(" ");
+//#endif
+//    // VERIFY: DIAGNOSTIC: print MAX5715 device register write
+//    // TODO: MAX5715_print_register_verbose(mosiData8_FF0000, mosiData16_00FFFF);
+//    // TODO: print_verbose_SPI_diagnostic(mosiData16_FF00, mosiData16_00FF, misoData16_FF00, misoData16_00FF);
+//    //
+//    int misoData16 = (misoData[0] << 8) | misoData[1];
+//    return misoData16;
+//}
+
+#endif
+
+
+#if APPLICATION_MAX5171 // hardware interface functions
+#endif
+
+
+#if APPLICATION_MAX11410 // hardware interface functions
+#endif
+
+
+#if APPLICATION_MAX12345 // hardware interface functions
+#endif
+
+
+//--------------------------------------------------
+// print banner message to serial port
+void print_banner()
+{
+#if HAS_DAPLINK_SERIAL
+    DAPLINKserial.printf("\r\n");
+# if defined(TARGET_MAX32630)
+    DAPLINKserial.printf("MAX32630");
+# elif defined(TARGET_MAX32625MBED)
+    DAPLINKserial.printf("MAX32625MBED");
+# elif defined(TARGET_NUCLEO_F446RE)
+    DAPLINKserial.printf("NUCLEO_F446RE");
+# elif defined(TARGET_NUCLEO_F401RE)
+    DAPLINKserial.printf("NUCLEO_F401RE");
+# elif defined(TARGET_LPC1768)
+    DAPLINKserial.printf("LPC1768");
+# else
+    // unknown target
+    DAPLINKserial.printf("unknownTarget");
+# endif
+    DAPLINKserial.printf(" DAPLINKserial\r\n");
+#endif // HAS_DAPLINK_SERIAL
+
+#if HAS_MICROUSBSERIAL
+    microUSBserial.printf("\r\n");
+# if defined(TARGET_MAX32630)
+    microUSBserial.printf("MAX32630");
+# elif defined(TARGET_MAX32625MBED)
+    microUSBserial.printf("MAX32625MBED");
+# elif defined(TARGET_NUCLEO_F446RE)
+    microUSBserial.printf("NUCLEO_F446RE");
+# elif defined(TARGET_NUCLEO_F401RE)
+    microUSBserial.printf("NUCLEO_F401RE");
+# elif defined(TARGET_LPC1768)
+    microUSBserial.printf("LPC1768");
+# else
+    // unknown target
+    microUSBserial.printf("unknownTarget");
+# endif
+    microUSBserial.printf(" microUSBserial\r\n");
+#endif // HAS_MICROUSBSERIAL
+}
+
+// DigitalInOut pin resource: print the pin index names to microUSBserial
+#if HAS_digitalInOuts
+void list_digitalInOutPins(Stream& serialStream)
+{
+#if HAS_digitalInOut0
+    serialStream.printf(" 0");
+#endif
+#if HAS_digitalInOut1
+    serialStream.printf(" 1");
+#endif
+#if HAS_digitalInOut2
+    serialStream.printf(" 2");
+#endif
+#if HAS_digitalInOut3
+    serialStream.printf(" 3");
+#endif
+#if HAS_digitalInOut4
+    serialStream.printf(" 4");
+#endif
+#if HAS_digitalInOut5
+    serialStream.printf(" 5");
+#endif
+#if HAS_digitalInOut6
+    serialStream.printf(" 6");
+#endif
+#if HAS_digitalInOut7
+    serialStream.printf(" 7");
+#endif
+#if HAS_digitalInOut8
+    serialStream.printf(" 8");
+#endif
+#if HAS_digitalInOut9
+    serialStream.printf(" 9");
+#endif
+#if HAS_digitalInOut10
+    serialStream.printf(" 10");
+#endif
+#if HAS_digitalInOut11
+    serialStream.printf(" 11");
+#endif
+#if HAS_digitalInOut12
+    serialStream.printf(" 12");
+#endif
+#if HAS_digitalInOut13
+    serialStream.printf(" 13");
+#endif
+#if HAS_digitalInOut14
+    serialStream.printf(" 14");
+#endif
+#if HAS_digitalInOut15
+    serialStream.printf(" 15");
+#endif
+#if HAS_digitalInOut16
+    serialStream.printf(" 16");
+#endif
+#if HAS_digitalInOut17
+    serialStream.printf(" 17");
+#endif
+}
+#endif
+
+// DigitalInOut pin resource: present?
+#if HAS_digitalInOuts
+bool has_digitalInOutPin(int cPinIndex)
+{
+    switch (cPinIndex)
+    {
+#if HAS_digitalInOut0
+        case '0': case 0x00: return true;
+#endif
+#if HAS_digitalInOut1
+        case '1': case 0x01: return true;
+#endif
+#if HAS_digitalInOut2
+        case '2': case 0x02: return true;
+#endif
+#if HAS_digitalInOut3
+        case '3': case 0x03: return true;
+#endif
+#if HAS_digitalInOut4
+        case '4': case 0x04: return true;
+#endif
+#if HAS_digitalInOut5
+        case '5': case 0x05: return true;
+#endif
+#if HAS_digitalInOut6
+        case '6': case 0x06: return true;
+#endif
+#if HAS_digitalInOut7
+        case '7': case 0x07: return true;
+#endif
+#if HAS_digitalInOut8
+        case '8': case 0x08: return true;
+#endif
+#if HAS_digitalInOut9
+        case '9': case 0x09: return true;
+#endif
+#if HAS_digitalInOut10
+        case 'a': case 0x0a: return true;
+#endif
+#if HAS_digitalInOut11
+        case 'b': case 0x0b: return true;
+#endif
+#if HAS_digitalInOut12
+        case 'c': case 0x0c: return true;
+#endif
+#if HAS_digitalInOut13
+        case 'd': case 0x0d: return true;
+#endif
+#if HAS_digitalInOut14
+        case 'e': case 0x0e: return true;
+#endif
+#if HAS_digitalInOut15
+        case 'f': case 0x0f: return true;
+#endif
+        default:
+            return false;
+    }
+}
+#endif
+
+// DigitalInOut pin resource: search index
+#if HAS_digitalInOuts
+DigitalInOut& find_digitalInOutPin(int cPinIndex)
+{
+    switch (cPinIndex)
+    {
+        default: // default to the first defined digitalInOut pin
+#if HAS_digitalInOut0
+        case '0': case 0x00: return digitalInOut0;
+#endif
+#if HAS_digitalInOut1
+        case '1': case 0x01: return digitalInOut1;
+#endif
+#if HAS_digitalInOut2
+        case '2': case 0x02: return digitalInOut2;
+#endif
+#if HAS_digitalInOut3
+        case '3': case 0x03: return digitalInOut3;
+#endif
+#if HAS_digitalInOut4
+        case '4': case 0x04: return digitalInOut4;
+#endif
+#if HAS_digitalInOut5
+        case '5': case 0x05: return digitalInOut5;
+#endif
+#if HAS_digitalInOut6
+        case '6': case 0x06: return digitalInOut6;
+#endif
+#if HAS_digitalInOut7
+        case '7': case 0x07: return digitalInOut7;
+#endif
+#if HAS_digitalInOut8
+        case '8': case 0x08: return digitalInOut8;
+#endif
+#if HAS_digitalInOut9
+        case '9': case 0x09: return digitalInOut9;
+#endif
+#if HAS_digitalInOut10
+        case 'a': case 0x0a: return digitalInOut10;
+#endif
+#if HAS_digitalInOut11
+        case 'b': case 0x0b: return digitalInOut11;
+#endif
+#if HAS_digitalInOut12
+        case 'c': case 0x0c: return digitalInOut12;
+#endif
+#if HAS_digitalInOut13
+        case 'd': case 0x0d: return digitalInOut13;
+#endif
+#if HAS_digitalInOut14
+        case 'e': case 0x0e: return digitalInOut14;
+#endif
+#if HAS_digitalInOut15
+        case 'f': case 0x0f: return digitalInOut15;
+#endif
+#if HAS_digitalInOut16
+        case 'g': case 0x10: return digitalInOut16;
+#endif
+#if HAS_digitalInOut17
+        case 'h': case 0x11: return digitalInOut17;
+#endif
+    }
+}
+#endif
+
+// AnalogIn pin resource: print the pin index names to microUSBserial
+#if HAS_analogIns
+void list_analogInPins(Stream& serialStream)
+{
+#if HAS_analogIn0
+    serialStream.printf(" 0");
+#endif
+#if HAS_analogIn1
+    serialStream.printf(" 1");
+#endif
+#if HAS_analogIn2
+    serialStream.printf(" 2");
+#endif
+#if HAS_analogIn3
+    serialStream.printf(" 3");
+#endif
+#if HAS_analogIn4
+    serialStream.printf(" 4");
+#endif
+#if HAS_analogIn5
+    serialStream.printf(" 5");
+#endif
+#if HAS_analogIn6
+    serialStream.printf(" 6");
+#endif
+#if HAS_analogIn7
+    serialStream.printf(" 7");
+#endif
+#if HAS_analogIn8
+    serialStream.printf(" 8");
+#endif
+#if HAS_analogIn9
+    serialStream.printf(" 9");
+#endif
+#if HAS_analogIn10
+    serialStream.printf(" a");
+#endif
+#if HAS_analogIn11
+    serialStream.printf(" b");
+#endif
+#if HAS_analogIn12
+    serialStream.printf(" c");
+#endif
+#if HAS_analogIn13
+    serialStream.printf(" d");
+#endif
+#if HAS_analogIn14
+    serialStream.printf(" e");
+#endif
+#if HAS_analogIn15
+    serialStream.printf(" f");
+#endif
+}
+#endif
+
+// AnalogIn pin resource: present?
+#if HAS_analogIns
+bool has_analogInPin(int cPinIndex)
+{
+    switch (cPinIndex)
+    {
+#if HAS_analogIn0
+        case '0': case 0x00: return true;
+#endif
+#if HAS_analogIn1
+        case '1': case 0x01: return true;
+#endif
+#if HAS_analogIn2
+        case '2': case 0x02: return true;
+#endif
+#if HAS_analogIn3
+        case '3': case 0x03: return true;
+#endif
+#if HAS_analogIn4
+        case '4': case 0x04: return true;
+#endif
+#if HAS_analogIn5
+        case '5': case 0x05: return true;
+#endif
+#if HAS_analogIn6
+        case '6': case 0x06: return true;
+#endif
+#if HAS_analogIn7
+        case '7': case 0x07: return true;
+#endif
+#if HAS_analogIn8
+        case '8': case 0x08: return true;
+#endif
+#if HAS_analogIn9
+        case '9': case 0x09: return true;
+#endif
+#if HAS_analogIn10
+        case 'a': case 0x0a: return true;
+#endif
+#if HAS_analogIn11
+        case 'b': case 0x0b: return true;
+#endif
+#if HAS_analogIn12
+        case 'c': case 0x0c: return true;
+#endif
+#if HAS_analogIn13
+        case 'd': case 0x0d: return true;
+#endif
+#if HAS_analogIn14
+        case 'e': case 0x0e: return true;
+#endif
+#if HAS_analogIn15
+        case 'f': case 0x0f: return true;
+#endif
+        default:
+            return false;
+    }
+}
+#endif
+
+// AnalogIn pin resource: search index
+#if HAS_analogIns
+AnalogIn& find_analogInPin(int cPinIndex)
+{
+    switch (cPinIndex)
+    {
+        default: // default to the first defined analogIn pin
+#if HAS_analogIn0
+        case '0': case 0x00: return analogIn0;
+#endif
+#if HAS_analogIn1
+        case '1': case 0x01: return analogIn1;
+#endif
+#if HAS_analogIn2
+        case '2': case 0x02: return analogIn2;
+#endif
+#if HAS_analogIn3
+        case '3': case 0x03: return analogIn3;
+#endif
+#if HAS_analogIn4
+        case '4': case 0x04: return analogIn4;
+#endif
+#if HAS_analogIn5
+        case '5': case 0x05: return analogIn5;
+#endif
+#if HAS_analogIn6
+        case '6': case 0x06: return analogIn6;
+#endif
+#if HAS_analogIn7
+        case '7': case 0x07: return analogIn7;
+#endif
+#if HAS_analogIn8
+        case '8': case 0x08: return analogIn8;
+#endif
+#if HAS_analogIn9
+        case '9': case 0x09: return analogIn9;
+#endif
+#if HAS_analogIn10
+        case 'a': case 0x0a: return analogIn10;
+#endif
+#if HAS_analogIn11
+        case 'b': case 0x0b: return analogIn11;
+#endif
+#if HAS_analogIn12
+        case 'c': case 0x0c: return analogIn12;
+#endif
+#if HAS_analogIn13
+        case 'd': case 0x0d: return analogIn13;
+#endif
+#if HAS_analogIn14
+        case 'e': case 0x0e: return analogIn14;
+#endif
+#if HAS_analogIn15
+        case 'f': case 0x0f: return analogIn15;
+#endif
+    }
+}
+#endif
+
+#if HAS_analogIns
+const float analogInPin_fullScaleVoltage[] = {
+# if defined(TARGET_MAX32630)
+    ADC_FULL_SCALE_VOLTAGE, // analogIn0
+    ADC_FULL_SCALE_VOLTAGE, // analogIn1
+    ADC_FULL_SCALE_VOLTAGE, // analogIn2
+    ADC_FULL_SCALE_VOLTAGE, // analogIn3
+    ADC_FULL_SCALE_VOLTAGE * 5.0f, // analogIn4 // AIN_4 = AIN0 / 5.0     fullscale is 6.0V
+    ADC_FULL_SCALE_VOLTAGE * 5.0f, // analogIn4 // AIN_5 = AIN1 / 5.0     fullscale is 6.0V
+    ADC_FULL_SCALE_VOLTAGE * 4.0f, // analogIn6 // AIN_6 = VDDB / 4.0     fullscale is 4.8V
+    ADC_FULL_SCALE_VOLTAGE, // analogIn7 // AIN_7 = VDD18          fullscale is 1.2V
+    ADC_FULL_SCALE_VOLTAGE, // analogIn8 // AIN_8 = VDD12          fullscale is 1.2V
+    ADC_FULL_SCALE_VOLTAGE * 2.0f, // analogIn9 // AIN_9 = VRTC / 2.0     fullscale is 2.4V
+    ADC_FULL_SCALE_VOLTAGE, // analogIn10  // AIN_10 = x undefined?
+    ADC_FULL_SCALE_VOLTAGE * 4.0f, // analogIn11 // AIN_11 = VDDIO / 4.0   fullscale is 4.8V
+    ADC_FULL_SCALE_VOLTAGE * 4.0f, // analogIn12 // AIN_12 = VDDIOH / 4.0  fullscale is 4.8V
+    ADC_FULL_SCALE_VOLTAGE, // analogIn13
+    ADC_FULL_SCALE_VOLTAGE, // analogIn14
+    ADC_FULL_SCALE_VOLTAGE // analogIn15
+#elif defined(TARGET_MAX32625MBED)
+    ADC_FULL_SCALE_VOLTAGE * 1.0f, // analogIn0 // fullscale is 1.2V
+    ADC_FULL_SCALE_VOLTAGE * 1.0f, // analogIn1 // fullscale is 1.2V
+    ADC_FULL_SCALE_VOLTAGE * 1.0f, // analogIn2 // fullscale is 1.2V
+    ADC_FULL_SCALE_VOLTAGE * 1.0f, // analogIn3 // fullscale is 1.2V
+    ADC_FULL_SCALE_VOLTAGE * 5.0f, // analogIn4 // AIN_4 = AIN0 / 5.0     fullscale is 6.0V
+    ADC_FULL_SCALE_VOLTAGE * 5.0f, // analogIn4 // AIN_5 = AIN1 / 5.0     fullscale is 6.0V
+    ADC_FULL_SCALE_VOLTAGE * 4.0f, // analogIn6 // AIN_6 = VDDB / 4.0     fullscale is 4.8V
+    ADC_FULL_SCALE_VOLTAGE, // analogIn7 // AIN_7 = VDD18          fullscale is 1.2V
+    ADC_FULL_SCALE_VOLTAGE, // analogIn8 // AIN_8 = VDD12          fullscale is 1.2V
+    ADC_FULL_SCALE_VOLTAGE * 2.0f, // analogIn9 // AIN_9 = VRTC / 2.0     fullscale is 2.4V
+    ADC_FULL_SCALE_VOLTAGE, // analogIn10  // AIN_10 = x undefined?
+    ADC_FULL_SCALE_VOLTAGE * 4.0f, // analogIn11 // AIN_11 = VDDIO / 4.0   fullscale is 4.8V
+    ADC_FULL_SCALE_VOLTAGE * 4.0f, // analogIn12 // AIN_12 = VDDIOH / 4.0  fullscale is 4.8V
+    ADC_FULL_SCALE_VOLTAGE, // analogIn13
+    ADC_FULL_SCALE_VOLTAGE, // analogIn14
+    ADC_FULL_SCALE_VOLTAGE // analogIn15
+#elif defined(TARGET_NUCLEO_F446RE)
+    ADC_FULL_SCALE_VOLTAGE, // analogIn0
+    ADC_FULL_SCALE_VOLTAGE, // analogIn1
+    ADC_FULL_SCALE_VOLTAGE, // analogIn2
+    ADC_FULL_SCALE_VOLTAGE, // analogIn3
+    ADC_FULL_SCALE_VOLTAGE, // analogIn4
+    ADC_FULL_SCALE_VOLTAGE, // analogIn5
+    ADC_FULL_SCALE_VOLTAGE, // analogIn6
+    ADC_FULL_SCALE_VOLTAGE, // analogIn7
+    ADC_FULL_SCALE_VOLTAGE, // analogIn8
+    ADC_FULL_SCALE_VOLTAGE, // analogIn9
+    ADC_FULL_SCALE_VOLTAGE, // analogIn10
+    ADC_FULL_SCALE_VOLTAGE, // analogIn11
+    ADC_FULL_SCALE_VOLTAGE, // analogIn12
+    ADC_FULL_SCALE_VOLTAGE, // analogIn13
+    ADC_FULL_SCALE_VOLTAGE, // analogIn14
+    ADC_FULL_SCALE_VOLTAGE // analogIn15
+#elif defined(TARGET_NUCLEO_F401RE)
+    ADC_FULL_SCALE_VOLTAGE, // analogIn0
+    ADC_FULL_SCALE_VOLTAGE, // analogIn1
+    ADC_FULL_SCALE_VOLTAGE, // analogIn2
+    ADC_FULL_SCALE_VOLTAGE, // analogIn3
+    ADC_FULL_SCALE_VOLTAGE, // analogIn4
+    ADC_FULL_SCALE_VOLTAGE, // analogIn5
+    ADC_FULL_SCALE_VOLTAGE, // analogIn6
+    ADC_FULL_SCALE_VOLTAGE, // analogIn7
+    ADC_FULL_SCALE_VOLTAGE, // analogIn8
+    ADC_FULL_SCALE_VOLTAGE, // analogIn9
+    ADC_FULL_SCALE_VOLTAGE, // analogIn10
+    ADC_FULL_SCALE_VOLTAGE, // analogIn11
+    ADC_FULL_SCALE_VOLTAGE, // analogIn12
+    ADC_FULL_SCALE_VOLTAGE, // analogIn13
+    ADC_FULL_SCALE_VOLTAGE, // analogIn14
+    ADC_FULL_SCALE_VOLTAGE // analogIn15
+//#elif defined(TARGET_LPC1768)
+#else
+    // unknown target
+    ADC_FULL_SCALE_VOLTAGE, // analogIn0
+    ADC_FULL_SCALE_VOLTAGE, // analogIn1
+    ADC_FULL_SCALE_VOLTAGE, // analogIn2
+    ADC_FULL_SCALE_VOLTAGE, // analogIn3
+    ADC_FULL_SCALE_VOLTAGE, // analogIn4
+    ADC_FULL_SCALE_VOLTAGE, // analogIn5
+    ADC_FULL_SCALE_VOLTAGE, // analogIn6
+    ADC_FULL_SCALE_VOLTAGE, // analogIn7
+    ADC_FULL_SCALE_VOLTAGE, // analogIn8
+    ADC_FULL_SCALE_VOLTAGE, // analogIn9
+    ADC_FULL_SCALE_VOLTAGE, // analogIn10
+    ADC_FULL_SCALE_VOLTAGE, // analogIn11
+    ADC_FULL_SCALE_VOLTAGE, // analogIn12
+    ADC_FULL_SCALE_VOLTAGE, // analogIn13
+    ADC_FULL_SCALE_VOLTAGE, // analogIn14
+    ADC_FULL_SCALE_VOLTAGE // analogIn15
+# endif
+};
+#endif
+
+// PwmOut pin resource: print the pin index names to microUSBserial
+#if HAS_pwmDrivers
+void list_pwmDriverPins(Stream& serialStream)
+{
+#if HAS_pwmDriver0
+    serialStream.printf(" 0");
+#endif
+#if HAS_pwmDriver1
+    serialStream.printf(" 1");
+#endif
+#if HAS_pwmDriver2
+    serialStream.printf(" 2");
+#endif
+#if HAS_pwmDriver3
+    serialStream.printf(" 3");
+#endif
+#if HAS_pwmDriver4
+    serialStream.printf(" 4");
+#endif
+#if HAS_pwmDriver5
+    serialStream.printf(" 5");
+#endif
+#if HAS_pwmDriver6
+    serialStream.printf(" 6");
+#endif
+#if HAS_pwmDriver7
+    serialStream.printf(" 7");
+#endif
+#if HAS_pwmDriver8
+    serialStream.printf(" 8");
+#endif
+#if HAS_pwmDriver9
+    serialStream.printf(" 9");
+#endif
+#if HAS_pwmDriver10
+    serialStream.printf(" a");
+#endif
+#if HAS_pwmDriver11
+    serialStream.printf(" b");
+#endif
+#if HAS_pwmDriver12
+    serialStream.printf(" c");
+#endif
+#if HAS_pwmDriver13
+    serialStream.printf(" d");
+#endif
+#if HAS_pwmDriver14
+    serialStream.printf(" e");
+#endif
+#if HAS_pwmDriver15
+    serialStream.printf(" f");
+#endif
+}
+#endif
+
+// PwmOut pin resource: present?
+#if HAS_pwmDrivers
+bool has_pwmDriverPin(int cPinIndex)
+{
+    switch (cPinIndex)
+    {
+#if HAS_pwmDriver0
+        case '0': case 0x00: return true;
+#endif
+#if HAS_pwmDriver1
+        case '1': case 0x01: return true;
+#endif
+#if HAS_pwmDriver2
+        case '2': case 0x02: return true;
+#endif
+#if HAS_pwmDriver3
+        case '3': case 0x03: return true;
+#endif
+#if HAS_pwmDriver4
+        case '4': case 0x04: return true;
+#endif
+#if HAS_pwmDriver5
+        case '5': case 0x05: return true;
+#endif
+#if HAS_pwmDriver6
+        case '6': case 0x06: return true;
+#endif
+#if HAS_pwmDriver7
+        case '7': case 0x07: return true;
+#endif
+#if HAS_pwmDriver8
+        case '8': case 0x08: return true;
+#endif
+#if HAS_pwmDriver9
+        case '9': case 0x09: return true;
+#endif
+#if HAS_pwmDriver10
+        case 'a': case 0x0a: return true;
+#endif
+#if HAS_pwmDriver11
+        case 'b': case 0x0b: return true;
+#endif
+#if HAS_pwmDriver12
+        case 'c': case 0x0c: return true;
+#endif
+#if HAS_pwmDriver13
+        case 'd': case 0x0d: return true;
+#endif
+#if HAS_pwmDriver14
+        case 'e': case 0x0e: return true;
+#endif
+#if HAS_pwmDriver15
+        case 'f': case 0x0f: return true;
+#endif
+        default:
+            return false;
+    }
+}
+#endif
+
+#if HAS_I2C // SUPPORT_I2C
+//--------------------------------------------------
+// Search I2C device address list
+//
+// @param[in] deviceAddress7First = I2C device address (slave address on I2C bus), 7-bits, RIGHT-justified.
+// @param[in] deviceAddress7Last = I2C device address (slave address on I2C bus), 7-bits, RIGHT-justified.
+// @param[in] numDevicesFoundLimit = maximum number of devices to detect before halting search; in case SCL stuck low or pullups missing.
+// @returns deviceAddress on success; 0 on failure
+// @post g_I2C_deviceAddress7 is updated with any device that did ACK
+//
+void HuntAttachedI2CDevices(CmdLine& cmdLine, uint8_t deviceAddress7First, uint8_t deviceAddress7Last,
+                            const uint8_t numDevicesFoundLimit = 20)
+{
+    // declare in narrower scope: MAX32625MBED I2C i2cMaster(...)
+    I2C i2cMaster(I2C0_SDA, I2C0_SCL); // sda scl TARGET_MAX32635MBED: P1_6, P1_7 Arduino 10-pin header
+    i2cMaster.frequency(g_I2C_SCL_Hz);
+
+    // %IP -- I2C probe
+    // TODO: i2c transfer
+    //const int addr7bit = 0x48;      // 7 bit I2C address
+    //const int addr8bit = 0x48 << 1; // 8bit I2C address, 0x90
+    // /* int  */   i2cMaster.read (int addr8bit, char *data, int length, bool repeated=false) // Read from an I2C slave.
+    // /* int  */   i2cMaster.read (int ack) // Read a single byte from the I2C bus.
+    // /* int  */   i2cMaster.write (int addr8bit, const char *data, int length, bool repeated=false) // Write to an I2C slave.
+    // /* int  */   i2cMaster.write (int data) // Write single byte out on the I2C bus.
+    // /* void */   i2cMaster.start (void) // Creates a start condition on the I2C bus.
+    // /* void */   i2cMaster.stop (void) // Creates a stop condition on the I2C bus.
+    // /* int */    i2cMaster.transfer (int addr8bit, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length, const event_callback_t &callback, int event=I2C_EVENT_TRANSFER_COMPLETE, bool repeated=false) // Start nonblocking I2C transfer. More...
+    // /* void */   i2cMaster.abort_transfer () // Abort the ongoing I2C transfer. More...
+
+    //const char probeWriteData[] = { 0x00 };
+    //int probeWriteDataLength = 1;
+    //bool isRepeatedStart = false;
+    cmdLine.serial().printf("I2C Probe {0x%2.2X (0x%2.2X >> 1) to 0x%2.2X (0x%2.2X >> 1)}, limit %d\r\n",
+                            deviceAddress7First,
+                            deviceAddress7First << 1,
+                            deviceAddress7Last,
+                            deviceAddress7Last << 1,
+                            numDevicesFoundLimit); // HuntAttachedI2CDevices
+    //~ const int i2cFileDescriptor = i2c_open_adapter(1);
+    uint8_t numDevicesFound = 0;
+    uint8_t last_valid_deviceAddress7 = 0;
+    for (uint8_t deviceAddress7 = deviceAddress7First; deviceAddress7 <= deviceAddress7Last; deviceAddress7++)
+    {
+        //cmdLine.serial().printf(" (0x%2.2X >> 1) ", (deviceAddress7 << 1));
+        //if (i2c_ioctl_I2C_SLAVE_i2cDeviceAddress7bits(i2cFileDescriptor, deviceAddress7) == 0)
+        int addr8bit = deviceAddress7 * 2;
+        //
+        // /* int  */   i2cMaster.write (int addr8bit, const char *data, int length, bool repeated=false) // Write to an I2C slave.
+        // Returns 0 on success (ack), nonzero on failure (nack)
+        //bool gotACK = (i2cMaster.write (addr8bit, probeWriteData, probeWriteDataLength, isRepeatedStart) == 0);
+        //
+        // SMBusQuick test
+        i2cMaster.start();
+        // /** Write single byte out on the I2C bus
+        //  *
+        //  *  @param data data to write out on bus
+        //  *
+        //  *  @returns
+        //  *    '0' - NAK was received
+        //  *    '1' - ACK was received,
+        //  *    '2' - timeout
+        //  */
+        // int write(int data);
+        int writeStatus = i2cMaster.write(addr8bit);
+        i2cMaster.stop();
+        bool gotACK = (writeStatus == 1); // ACK was received
+        if (writeStatus == 2) // timeout
+        {
+            cmdLine.serial().printf("- timeout\r\n");
+        }
+        //
+        if (gotACK)
+        {
+            // @return status; error if (fileDescriptor < 0)
+            cmdLine.serial().printf("+ ADDR=0x%2.2X (0x%2.2X >> 1) ACK\r\n", deviceAddress7, (deviceAddress7 << 1));
+            numDevicesFound++;
+            last_valid_deviceAddress7 = deviceAddress7;
+            if (numDevicesFound > numDevicesFoundLimit)
+            {
+                break;
+            }
+            continue;
+        }
+    }
+    if (numDevicesFound == 0)
+    {
+        cmdLine.serial().printf("- No I2C devices found. Maybe SCL/SDA are swapped?\r\n");
+    }
+    else if (numDevicesFound > numDevicesFoundLimit)
+    {
+        cmdLine.serial().printf("- Many I2C devices found. SCL/SDA missing pullup resistors? SCL stuck low?\r\n");
+    }
+    else
+    {
+        //~ i2c_ioctl_I2C_SLAVE_i2cDeviceAddress7bits(i2cFileDescriptor, last_valid_deviceAddress7);
+        g_I2C_deviceAddress7 = last_valid_deviceAddress7;
+    }
+    //~ i2c_close(i2cFileDescriptor);
+}
+#endif // SUPPORT_I2C
+
+//--------------------------------------------------
+// periodic interrupt timer onTimerTick handler triggered by Ticker
+// analogIn0 (MAX32630:AIN_4 = AIN0 / 5.0) controls angular speed
+// analogIn1 (MAX32630:AIN_5 = AIN1 / 5.0) controls PWM duty cycle
+// note: measured 500ns overhead for MAX32630FTHR digitalInOut1.write(0); digitalInOut1.write(1);
+#if USE_PERIODIC_TIMER
+void onTimerTick() {
+} // onTimerTick
+#endif
+
+#if USE_PERIODIC_TIMER
+// periodic interrupt timer command handlers -- enable timer
+void cmd_TE()
+{
+    //us_timestamp_t interval_usec = 100000; // 100ms
+    periodicInterruptTimer_interval_usec = 100000; // 100ms
+#  if HAS_DAPLINK_SERIAL
+    DAPLINKserial.printf("  Timer Enable %d us\r\n", periodicInterruptTimer_interval_usec);
+#  endif
+    microUSBserial.printf(" Timer Enable %d us", periodicInterruptTimer_interval_usec);
+    periodicInterruptTimer.attach_us(&onTimerTick, periodicInterruptTimer_interval_usec);
+    // -- periodicInterruptTimer.attach(&onTimerTick, interval_sec); // the address of the function to be attached (onTimerTick) and the interval (2 seconds)
+    // -- periodicInterruptTimer.attach_us(&onTimerTick, interval_usec); // the address of the function to be attached (onTimerTick) and the interval (2 seconds)
+    // -- periodicInterruptTimer.attach(Callback<void()> func, float t);
+    // -- periodicInterruptTimer.attach_us(Callback<void()> func, us_timestamp_t t);
+    // TODO1: cmd_T add cSubCommand to change interval of Ticker periodic interrupt timer
+}
+#endif
+
+#if USE_PERIODIC_TIMER
+// periodic interrupt timer command handlers -- disable timer
+void cmd_TD()
+{
+#  if HAS_DAPLINK_SERIAL
+    DAPLINKserial.printf("  Timer Disable\r\n");
+#  endif
+    microUSBserial.printf(" Timer Disable ");
+    periodicInterruptTimer.detach(); // Detach the function
+}
+#endif
+
+//--------------------------------------------------
+// When user presses button BUTTON1, perform a demo configuration
+#if HAS_BUTTON1_DEMO_INTERRUPT
+void onButton1FallingEdge(void)
+{
+    void SelfTest(CmdLine & cmdLine);
+
+    // TODO1: BUTTON1 demo configuration LED blink
+    //~ 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
+    //~ led1 = LED_ON; led2 = LED_ON; led3 = LED_OFF; // diagnostic rbg led RED+GREEN=YELLOW
+    //~ rgb_led.yellow(); // diagnostic rbg led RED+GREEN=YELLOW
+    //~ ThisThread::sleep_for(250); // [since mbed-os-5.10] vs Thread::wait(250);
+    //~ led1 = LED_OFF; led2 = LED_ON; led3 = LED_OFF; // diagnostic rbg led GREEN
+    //~ rgb_led.black(); // diagnostic rbg led BLACK
+    //~ ThisThread::sleep_for(250); // [since mbed-os-5.10] vs Thread::wait(250);
+    //~ led1 = LED_ON; led2 = LED_ON; led3 = LED_OFF; // diagnostic rbg led RED+GREEN=YELLOW
+    //~ rgb_led.yellow(); // diagnostic rbg led RED+GREEN=YELLOW
+    //~ ThisThread::sleep_for(250); // [since mbed-os-5.10] vs Thread::wait(250);
+    //~ led1 = LED_OFF; led2 = LED_ON; led3 = LED_OFF; // diagnostic rbg led GREEN
+    //~ rgb_led.black(); // diagnostic rbg led BLACK
+    //~ ThisThread::sleep_for(250); // [since mbed-os-5.10] vs Thread::wait(250);
+    //~ rgb_led.yellow(); // diagnostic rbg led RED+GREEN=YELLOW
+
+#if HAS_MICROUSBSERIAL
+    SelfTest(cmdLine_microUSBserial);
+#elif HAS_DAPLINK_SERIAL
+    SelfTest(cmdLine_DAPLINKserial);
+#endif
+
+#if 0 // APPLICATION_MAX5715 // onButton1FallingEdge BUTTON1 demo configuration MAX5715BOB
+    //~ cmdLine.serial().printf("MAX5715_REF(REF_AlwaysOn_2V500)");
+    g_MAX5715_device.REF(MAX5715::REF_AlwaysOn_2V500);
+
+    uint16_t code = 4095;
+    //~ cmdLine.serial().printf("CODEallLOADall code=%d", code);
+    g_MAX5715_device.CODEallLOADall(code);
+#endif // APPLICATION_MAX5715
+
+}
+#endif // HAS_BUTTON1_DEMO_INTERRUPT
+
+//--------------------------------------------------
+// When user presses button BUTTON2, perform a demo configuration
+#if HAS_BUTTON2_DEMO_INTERRUPT
+void onButton2FallingEdge(void)
+{
+    // TODO1: BUTTON2 demo configuration LED blink
+    //~ led1 = LED_ON; led2 = LED_ON; led3 = LED_OFF; // diagnostic rbg led RED+GREEN=YELLOW
+    //~ rgb_led.yellow(); // diagnostic rbg led RED+GREEN=YELLOW
+    // ThisThread::sleep_for(250); // [since mbed-os-5.10] vs Thread::wait(250);
+    // led1 = LED_OFF; led2 = LED_ON; led3 = LED_OFF; // diagnostic rbg led GREEN
+    //~ rgb_led.green(); // diagnostic rbg led GREEN
+    // ThisThread::sleep_for(250); // [since mbed-os-5.10] vs Thread::wait(250);
+    // led1 = LED_ON; led2 = LED_ON; led3 = LED_OFF; // diagnostic rbg led RED+GREEN=YELLOW
+    //~ rgb_led.yellow(); // diagnostic rbg led RED+GREEN=YELLOW
+    // ThisThread::sleep_for(250); // [since mbed-os-5.10] vs Thread::wait(250);
+    // led1 = LED_OFF; led2 = LED_ON; led3 = LED_OFF; // diagnostic rbg led GREEN
+    //~ rgb_led.green(); // diagnostic rbg led GREEN
+    // ThisThread::sleep_for(250); // [since mbed-os-5.10] vs Thread::wait(250);
+
+#if APPLICATION_MAX5715 // onButton2FallingEdge BUTTON2 demo configuration MAX5715BOB
+    //~ cmdLine.serial().printf("MAX5715_REF(REF_AlwaysOn_2V048)");
+    g_MAX5715_device.REF(MAX5715::REF_AlwaysOn_2V048);
+    //
+    uint16_t ch = 0;
+    uint16_t code = 0xccc;
+    //~ cmdLine.serial().printf("CODEnLOADn ch=%d code=%d", ch, code);
+    g_MAX5715_device.CODEnLOADn(ch, code);
+    //
+    ch = 1;
+    code = 0x800;
+    //~ cmdLine.serial().printf("CODEnLOADn ch=%d code=%d", ch, code);
+    g_MAX5715_device.CODEnLOADn(ch, code);
+    //
+    ch = 2;
+    code = 0x666;
+    //~ cmdLine.serial().printf("CODEnLOADn ch=%d code=%d", ch, code);
+    g_MAX5715_device.CODEnLOADn(ch, code);
+    //
+    ch = 3;
+    code = 0xFFF;
+    //~ cmdLine.serial().printf("CODEnLOADn ch=%d code=%d", ch, code);
+    g_MAX5715_device.CODEnLOADn(ch, code);
+#elif APPLICATION_MAX11131 // onButton2FallingEdge BUTTON2 demo configuration MAX11131BOB
+    // TODO1: demo
+    // MAX11131 > 4
+    // ScanStandardExternalClock ch=9 pm=0 id=1
+    // ScanRead_nWords_chanID nWords=10
+    //  ch=0 xu=2964 = 0x0b94 = 1.8091V
+    //  ch=1 xu=2227 = 0x08b3 = 1.3593V
+    //  ch=2 xu=1570 = 0x0622 = 0.9583V
+    //  ch=3 xu=865 = 0x0361 = 0.5280V
+    //  ch=4 xu=630 = 0x0276 = 0.3845V
+    //  ch=5 xu=594 = 0x0252 = 0.3625V
+    //  ch=6 xu=461 = 0x01cd = 0.2814V
+    //  ch=7 xu=364 = 0x016c = 0.2222V
+    //  ch=8 xu=480 = 0x01e0 = 0.2930V
+    //  ch=9 xu=616 = 0x0268 = 0.3760V
+    g_MAX11131_device.channelNumber_0_15 = 9;
+    g_MAX11131_device.PowerManagement_0_2 = 0;
+    g_MAX11131_device.chan_id_0_1 = 1;
+    g_MAX11131_device.NumWords = g_MAX11131_device.ScanStandardExternalClock();
+    //
+    // Read raw ADC codes from device into AINcode[] and RAW_misoData16[]
+    // @pre one of the MAX11311_Scan functions was called, setting g_MAX11131_device.NumWords
+    g_MAX11131_device.ReadAINcode();
+    // @post RAW_misoData16[index] contains the raw SPI Master-In,Slave-Out data
+    // @post AINcode[NUM_CHANNELS] contains the latest readings in LSBs
+    //
+    // TODO: compare with mbed/Arduino AIN0-AIN3
+    //
+#elif APPLICATION_MAX5171 // onButton2FallingEdge BUTTON2 demo configuration MAX5171BOB
+    // TODO: demo
+    uint16_t code = 0xccc;
+    g_MAX5171_device.CODE(code);
+#elif APPLICATION_MAX11410 // onButton2FallingEdge BUTTON2 demo configuration MAX11410BOB
+    // TODO: demo
+    g_MAX11410_device.CODEnLOADn(ch, code);
+#elif APPLICATION_MAX12345 // onButton2FallingEdge BUTTON2 demo configuration MAX12345BOB
+    // TODO: demo
+    g_MAX12345_device.CODEnLOADn(ch, code);
+#endif // APPLICATION_MAX5715
+    rgb_led.blue(); // diagnostic rbg led BLUE
+
+}
+#endif // HAS_BUTTON2_DEMO_INTERRUPT
+
+//--------------------------------------------------
+// TODO1: use MaximTinyTester encapsulate SelfTest support functions
+#if USE_MAXIMTINYTESTER
+#else // USE_MAXIMTINYTESTER
+int g_SelfTest_nPass = 0; // PASS test counter used by SelfTest()
+int g_SelfTest_nFail = 0; // FAIL test counter used by SelfTest()
+#endif // USE_MAXIMTINYTESTER
+//--------------------------------------------------
+#if USE_MAXIMTINYTESTER
+#else // USE_MAXIMTINYTESTER
+void SelfTest_PASS(CmdLine& cmdLine)
+{
+    ++g_SelfTest_nPass;
+    cmdLine.serial().printf("\r\n+PASS ");
+}
+#endif // USE_MAXIMTINYTESTER
+//--------------------------------------------------
+#if USE_MAXIMTINYTESTER
+#else // USE_MAXIMTINYTESTER
+void SelfTest_FAIL(CmdLine& cmdLine)
+{
+    ++g_SelfTest_nFail;
+    cmdLine.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
+}
+#endif // USE_MAXIMTINYTESTER
+//--------------------------------------------------
+void SelfTest_print_DACCodeOfVoltage(CmdLine& cmdLine, double voltageV)
+{
+    cmdLine.serial().printf("DACCodeOfVoltage(%6.4fV)", voltageV);
+    // For 12-bit DAC, dtostrf width, precision = 6, 4 i.e. 0.0001
+    // For 14-bit DAC, dtostrf width, precision = 7, 5 i.e. 0.00001
+    //~ dtostrf(voltageV, 6, 4, strOutLineBuffer); // value, width, precision, char* buffer
+    //~ cmdLine.serial().printf(strOutLineBuffer);
+    //~ cmdLine.serial().printf("V)");
+}
+//--------------------------------------------------
+#if APPLICATION_MAX5715 // SelfTest
+#if USE_MAXIMTINYTESTER
+#else // USE_MAXIMTINYTESTER
+void SelfTest_DACCodeOfVoltage_Expect(CmdLine& cmdLine, double voltageV, uint16_t expect_result)
+{
+    uint16_t actual_result = g_MAX5715_device.DACCodeOfVoltage(voltageV);
+    if (actual_result != expect_result)
+    {
+        SelfTest_FAIL(cmdLine);
+        SelfTest_print_DACCodeOfVoltage(cmdLine, voltageV);
+        cmdLine.serial().printf(" expect %d", expect_result);
+        cmdLine.serial().printf(" but got %d", actual_result);
+    }
+    else
+    {
+        SelfTest_PASS(cmdLine);
+        SelfTest_print_DACCodeOfVoltage(cmdLine, voltageV);
+        cmdLine.serial().printf(" expect %d", expect_result);
+    }
+    //~ cmdLine.serial().printf("\r\n");
+}
+#endif // APPLICATION_MAX5715
+#endif // USE_MAXIMTINYTESTER
+//--------------------------------------------------
+#if APPLICATION_MAX5171 // SelfTest
+#if USE_MAXIMTINYTESTER
+#else // USE_MAXIMTINYTESTER
+void SelfTest_DACCodeOfVoltage_Expect(CmdLine& cmdLine, double voltageV, uint16_t expect_result)
+{
+    uint16_t actual_result = g_MAX5171_device.DACCodeOfVoltage(voltageV);
+    if (actual_result != expect_result)
+    {
+        SelfTest_FAIL(cmdLine);
+        SelfTest_print_DACCodeOfVoltage(cmdLine, voltageV);
+        cmdLine.serial().printf(" expect %d", expect_result);
+        cmdLine.serial().printf(" but got %d", actual_result);
+    }
+    else
+    {
+        SelfTest_PASS(cmdLine);
+        SelfTest_print_DACCodeOfVoltage(cmdLine, voltageV);
+        cmdLine.serial().printf(" expect %d", expect_result);
+    }
+    //~ cmdLine.serial().printf("\r\n");
+}
+#endif // USE_MAXIMTINYTESTER
+#endif // APPLICATION_MAX5171
+//--------------------------------------------------
+#if APPLICATION_MAX5715 // SelfTest
+#if USE_MAXIMTINYTESTER
+#else // USE_MAXIMTINYTESTER
+void SelfTest_print_VoltageOfCode(CmdLine& cmdLine, uint16_t value_u12)
+{
+    cmdLine.serial().printf("VoltageOfCode(%d)", value_u12);
+    //~ dtostrf(voltageV, 6, 4, strOutLineBuffer); // value, width, precision, char* buffer
+    //~ cmdLine.serial().printf(strOutLineBuffer);
+    //~ cmdLine.serial().printf(")");
+}
+/* SelfTest_VoltageOfCode_Expect
+ *
+ * TODO: document this function
+ * This header was inserted by uncrustify; see uncrustify_func_header.txt.
+ *
+ */
+void SelfTest_VoltageOfCode_Expect(CmdLine& cmdLine, uint16_t value_u12, double expect_result)
+{
+    double actual_result = g_MAX5715_device.VoltageOfCode(value_u12);
+    double err_result = (actual_result - expect_result);
+    double one_LSB = (g_MAX5715_device.VRef / 4095); // 12-bit DAC FS
+    double err_threshold = one_LSB;
+    if (( -err_threshold < err_result) && ( err_result < err_threshold))
+    {
+        SelfTest_PASS(cmdLine);
+        SelfTest_print_VoltageOfCode(cmdLine, value_u12);
+        cmdLine.serial().printf(" expect %6.6f", expect_result);
+        //~ dtostrf(expect_result, 6, 6, strOutLineBuffer); // value, width, precision, char* buffer
+        //~ cmdLine.serial().printf(strOutLineBuffer);
+    }
+    else
+    {
+        SelfTest_FAIL(cmdLine);
+        SelfTest_print_VoltageOfCode(cmdLine, value_u12);
+        cmdLine.serial().printf(" expect %6.6f", expect_result);
+        //~ dtostrf(expect_result, 6, 6, strOutLineBuffer); // value, width, precision, char* buffer
+        //~ cmdLine.serial().printf(strOutLineBuffer);
+        cmdLine.serial().printf(" but got %6.6f", actual_result);
+        //~ dtostrf(actual_result, 6, 6, strOutLineBuffer); // value, width, precision, char* buffer
+        //~ cmdLine.serial().printf(strOutLineBuffer);
+        cmdLine.serial().printf(" err=%6.6f", err_result);
+        //~ dtostrf( err_result, 6, 6, strOutLineBuffer); // value, width, precision, char* buffer
+        //~ cmdLine.serial().printf(strOutLineBuffer);
+    }
+    //~ cmdLine.serial().printf("\r\n");
+}
+#endif // USE_MAXIMTINYTESTER
+#endif // APPLICATION_MAX5715
+//--------------------------------------------------
+#if APPLICATION_MAX5171 // SelfTest
+void SelfTest_print_VoltageOfCode(CmdLine& cmdLine, uint16_t value_u14)
+{
+    cmdLine.serial().printf("VoltageOfCode(%d)", value_u14);
+}
+#if USE_MAXIMTINYTESTER
+#else // USE_MAXIMTINYTESTER
+/* SelfTest_VoltageOfCode_Expect
+ *
+ * TODO: document this function
+ * This header was inserted by uncrustify; see uncrustify_func_header.txt.
+ *
+ */
+void SelfTest_VoltageOfCode_Expect(CmdLine& cmdLine, uint16_t value_u14, double expect_result)
+{
+    double actual_result = g_MAX5171_device.VoltageOfCode(value_u14);
+    double err_result = (actual_result - expect_result);
+    double one_LSB = (g_MAX5171_device.VRef / 16383); // 14-bit DAC FS
+    double err_threshold = one_LSB;
+    if (( -err_threshold < err_result) && ( err_result < err_threshold))
+    {
+        SelfTest_PASS(cmdLine);
+        SelfTest_print_VoltageOfCode(cmdLine, value_u14);
+        cmdLine.serial().printf(" expect %6.6f", expect_result);
+        //~ dtostrf(expect_result, 6, 6, strOutLineBuffer); // value, width, precision, char* buffer
+        //~ cmdLine.serial().printf(strOutLineBuffer);
+    }
+    else
+    {
+        SelfTest_FAIL(cmdLine);
+        SelfTest_print_VoltageOfCode(cmdLine, value_u14);
+        cmdLine.serial().printf(" expect %6.6f", expect_result);
+        //~ dtostrf(expect_result, 6, 6, strOutLineBuffer); // value, width, precision, char* buffer
+        //~ cmdLine.serial().printf(strOutLineBuffer);
+        cmdLine.serial().printf(" but got %6.6f", actual_result);
+        //~ dtostrf(actual_result, 6, 6, strOutLineBuffer); // value, width, precision, char* buffer
+        //~ cmdLine.serial().printf(strOutLineBuffer);
+        cmdLine.serial().printf(" err=%6.6f", err_result);
+        //~ dtostrf( err_result, 6, 6, strOutLineBuffer); // value, width, precision, char* buffer
+        //~ cmdLine.serial().printf(strOutLineBuffer);
+    }
+    //~ cmdLine.serial().printf("\r\n");
+}
+#endif // USE_MAXIMTINYTESTER
+#endif // APPLICATION_MAX5171
+//--------------------------------------------------
+#if USE_MAXIMTINYTESTER
+#else // USE_MAXIMTINYTESTER
+bool SelfTest_AnalogInput_Expect_ch_V(CmdLine& cmdLine, int pinIndex, double expect_result,
+                                      double err_threshold = 0.030)
+{
+#if analogIn4_IS_HIGH_RANGE_OF_analogIn0
+    // Platform board uses AIN4,AIN5,.. as high range of AIN0,AIN1,..
+    // low range channels AIN0, AIN1, AIN2, AIN3
+    int pinIndexL = ((pinIndex >= 4) ? (pinIndex - 4) : (pinIndex + 0));
+    // high range channels AIN4, AIN5
+    int pinIndexH = ((pinIndex >= 4) ? (pinIndex + 0) : (pinIndex + 4));
+    //
+    // low range channels AIN0, AIN1, AIN2, AIN3
+    int cPinIndexL = '0' + pinIndexL;
+    AnalogIn& analogInPinL = find_analogInPin(cPinIndexL);
+    float adc_full_scale_voltageL = analogInPin_fullScaleVoltage[pinIndexL];
+    float normValueL_0_1 = analogInPinL.read();
+    //
+    // high range channels AIN4, AIN5
+    int cPinIndexH = '0' + pinIndexH;
+    AnalogIn& analogInPinH = find_analogInPin(cPinIndexH);
+    float adc_full_scale_voltageH = analogInPin_fullScaleVoltage[pinIndexH];
+    float normValueH_0_1 = analogInPinH.read();
+    //
+    double actual_result = (pinIndex >= 4)
+                           ? (normValueH_0_1 * adc_full_scale_voltageH)
+                           : (normValueL_0_1 * adc_full_scale_voltageL);
+#else // analogIn4_IS_HIGH_RANGE_OF_analogIn0
+    // Platform board uses simple analog inputs
+    int cPinIndex = '0' + pinIndex;
+    AnalogIn& analogInPin = find_analogInPin(cPinIndex);
+    float adc_full_scale_voltage = analogInPin_fullScaleVoltage[pinIndex];
+    float normValue_0_1 = analogInPin.read();
+    double actual_result = normValue_0_1 * adc_full_scale_voltage;
+#endif // analogIn4_IS_HIGH_RANGE_OF_analogIn0
+    double err_result = (actual_result - expect_result);
+    //double err_threshold = 0.030; // 30mV
+    if (( -err_threshold < err_result) && ( err_result < err_threshold))
+    {
+        SelfTest_PASS(cmdLine);
+        //~ SelfTest_print_VoltageOfCode(cmdLine, value_u12);
+#if analogIn4_IS_HIGH_RANGE_OF_analogIn0
+        // Platform board uses AIN4,AIN5,.. as high range of AIN0,AIN1,..
+        cmdLine.serial().printf("AIN%c = %7.3f%% = %1.3fV  AIN%c = %7.3f%% = %1.3fV  ",
+                                cPinIndexL,
+                                normValueL_0_1 * 100.0,
+                                normValueL_0_1 * adc_full_scale_voltageL,
+                                cPinIndexH,
+                                normValueH_0_1 * 100.0,
+                                normValueH_0_1 * adc_full_scale_voltageH
+                                );
+#else // analogIn4_IS_HIGH_RANGE_OF_analogIn0
+        // Platform board uses simple analog inputs
+        cmdLine.serial().printf("AIN%c = %7.3f%% = %1.3fV  ",
+                                cPinIndex,
+                                normValue_0_1 * 100.0,
+                                normValue_0_1 * adc_full_scale_voltage
+                                );
+#endif // analogIn4_IS_HIGH_RANGE_OF_analogIn0
+        //
+        cmdLine.serial().printf(" expect %6.6f +/- %6.6f", expect_result, err_threshold);
+        //~ dtostrf(expect_result, 6, 6, strOutLineBuffer); // value, width, precision, char* buffer
+        //~ cmdLine.serial().printf(strOutLineBuffer);
+        return true;
+    }
+    else
+    {
+        SelfTest_FAIL(cmdLine);
+        //~ SelfTest_print_VoltageOfCode(cmdLine, value_u12);
+#if analogIn4_IS_HIGH_RANGE_OF_analogIn0
+        // Platform board uses AIN4,AIN5,.. as high range of AIN0,AIN1,..
+        cmdLine.serial().printf("AIN%c = %7.3f%% = %1.3fV  AIN%c = %7.3f%% = %1.3fV  ",
+                                cPinIndexL,
+                                normValueL_0_1 * 100.0,
+                                normValueL_0_1 * adc_full_scale_voltageL,
+                                cPinIndexH,
+                                normValueH_0_1 * 100.0,
+                                normValueH_0_1 * adc_full_scale_voltageH
+                                );
+#else // analogIn4_IS_HIGH_RANGE_OF_analogIn0
+        // Platform board uses simple analog inputs
+        cmdLine.serial().printf("AIN%c = %7.3f%% = %1.3fV  ",
+                                cPinIndex,
+                                normValue_0_1 * 100.0,
+                                normValue_0_1 * adc_full_scale_voltage
+                                );
+#endif // analogIn4_IS_HIGH_RANGE_OF_analogIn0
+        //
+        cmdLine.serial().printf(" expect %6.6f +/- %6.6f", expect_result, err_threshold);
+        //~ dtostrf(expect_result, 6, 6, strOutLineBuffer); // value, width, precision, char* buffer
+        //~ cmdLine.serial().printf(strOutLineBuffer);
+        cmdLine.serial().printf(" but got %6.6f", actual_result);
+        //~ dtostrf(actual_result, 6, 6, strOutLineBuffer); // value, width, precision, char* buffer
+        //~ cmdLine.serial().printf(strOutLineBuffer);
+        cmdLine.serial().printf(" err=%6.6f", err_result);
+        //~ dtostrf( err_result, 6, 6, strOutLineBuffer); // value, width, precision, char* buffer
+        //~ cmdLine.serial().printf(strOutLineBuffer);
+    }
+    //~ cmdLine.serial().printf("\r\n");
+    return false;
+}
+#endif // USE_MAXIMTINYTESTER
+//--------------------------------------------------
+#if APPLICATION_MAX5715 // SelfTest
+void SelfTest_print_Vref(CmdLine & cmdLine)
+{
+    cmdLine.serial().printf("VRef = %6.4fV  LSB=%6.4fV", g_MAX5715_device.VRef, (g_MAX5715_device.VRef / 4095));
+    //~ dtostrf(g_MAX5715_device.VRef, 6, 4, strOutLineBuffer); // value, width, precision, char* buffer
+    //~ cmdLine.serial().printf(strOutLineBuffer);
+    //~ cmdLine.serial().printf("V  LSB=");
+    // For 12-bit DAC, dtostrf width, precision = 6, 4 i.e. 0.0001
+    // For 14-bit DAC, dtostrf width, precision = 7, 5 i.e. 0.00001
+    //~ dtostrf( (g_MAX5715_device.VRef / 4095), 6, 4, strOutLineBuffer); // value, width, precision, char* buffer
+    //~ cmdLine.serial().printf(strOutLineBuffer);
+    //~ cmdLine.serial().printf("V");
+}
+#endif // APPLICATION_MAX5715
+//--------------------------------------------------
+#if APPLICATION_MAX5171 // SelfTest
+void SelfTest_print_Vref(CmdLine & cmdLine)
+{
+    cmdLine.serial().printf("VRef = %7.5fV  LSB=%7.5fV", g_MAX5171_device.VRef, (g_MAX5171_device.VRef / 16383));
+    // For 12-bit DAC, dtostrf width, precision = 6, 4 i.e. 0.0001
+    // For 14-bit DAC, dtostrf width, precision = 7, 5 i.e. 0.00001
+}
+#endif // APPLICATION_MAX5171
+//--------------------------------------------------
+#if HAS_SPI2_MAX541
+MAX541 max541(spi2_max541, spi2_max541_cs);
+#endif
+//--------------------------------------------------
+bool SelfTest_MAX541_Voltage(CmdLine & cmdLine, MAX541 &max541, double voltageV)
+{
+    max541.Set_Voltage(voltageV);
+    // cmdLine.serial().printf("\r\n      Test Fixture: MAX541 set output to %1.3fV = code 0x%4.4x", max541.Get_Voltage(), max541.Get_Code());
+    cmdLine.serial().printf("\r\n      Test Fixture: MAX541 set output to 0x%4.4x = %1.3fV",
+                            max541.Get_Code(), max541.Get_Voltage());
+#if USE_MAXIMTINYTESTER
+#if analogIn4_IS_HIGH_RANGE_OF_analogIn0
+    // Platform board uses AIN4,AIN5,.. as high range of AIN0,AIN1,..
+    MaximTinyTester tinyTester(cmdLine, analogIn4, analogIn5, analogIn2, analogIn3, analogIn0, analogIn4);
+    tinyTester.analogInPin_fullScaleVoltage[0] = analogInPin_fullScaleVoltage[4]; // board support
+    tinyTester.analogInPin_fullScaleVoltage[1] = analogInPin_fullScaleVoltage[5]; // board support
+    tinyTester.analogInPin_fullScaleVoltage[2] = analogInPin_fullScaleVoltage[2]; // board support
+    tinyTester.analogInPin_fullScaleVoltage[3] = analogInPin_fullScaleVoltage[3]; // board support
+    tinyTester.analogInPin_fullScaleVoltage[4] = analogInPin_fullScaleVoltage[0]; // board support
+    tinyTester.analogInPin_fullScaleVoltage[5] = analogInPin_fullScaleVoltage[1]; // board support
+    // low range channels AIN0, AIN1, AIN2, AIN3
+#else // analogIn4_IS_HIGH_RANGE_OF_analogIn0
+    // Platform board uses simple analog inputs
+    MaximTinyTester tinyTester(cmdLine, analogIn0, analogIn1, analogIn2, analogIn3, analogIn4, analogIn5);
+    tinyTester.analogInPin_fullScaleVoltage[0] = analogInPin_fullScaleVoltage[0]; // board support
+    tinyTester.analogInPin_fullScaleVoltage[1] = analogInPin_fullScaleVoltage[1]; // board support
+    tinyTester.analogInPin_fullScaleVoltage[2] = analogInPin_fullScaleVoltage[2]; // board support
+    tinyTester.analogInPin_fullScaleVoltage[3] = analogInPin_fullScaleVoltage[3]; // board support
+    tinyTester.analogInPin_fullScaleVoltage[4] = analogInPin_fullScaleVoltage[4]; // board support
+    tinyTester.analogInPin_fullScaleVoltage[5] = analogInPin_fullScaleVoltage[5]; // board support
+#endif
+    // TODO: tinyTester.AnalogIn0_Read_Expect_voltageV replaces SelfTest_AnalogInput_Expect_ch_V
+    tinyTester.err_threshold = 0.100;
+    return tinyTester.AnalogIn0_Read_Expect_voltageV(voltageV);
+#else // USE_MAXIMTINYTESTER
+    return SelfTest_AnalogInput_Expect_ch_V(cmdLine, 4, voltageV, 0.100);
+#endif // USE_MAXIMTINYTESTER
+}
+//--------------------------------------------------
+#if APPLICATION_MAX11131
+bool SelfTest_MAX11131_EOC_expect(CmdLine & cmdLine, int expect_EOC_value, const char *expect_description)
+{
+    int actual_EOC_value = -1;
+    for (int retry_count = 0; retry_count < 10; retry_count++) {
+        actual_EOC_value = g_MAX11131_device.EOCinputValue();
+        if (actual_EOC_value == expect_EOC_value) {
+            SelfTest_PASS(cmdLine);
+            cmdLine.serial().printf("EOC signal=%d %s", expect_EOC_value, expect_description);
+            return true;
+        }
+        // EOC condition not met, retry for a while until give up
+        wait_ms(100); // delay
+    }
+    cmdLine.serial().printf("\r\n!WARN "); // SelfTest_FAIL(cmdLine);
+    cmdLine.serial().printf("expected EOC signal=%d %s", expect_EOC_value, expect_description);
+    cmdLine.serial().printf(", but got actual EOC=%d", actual_EOC_value);
+    cmdLine.serial().printf(", missing CNVST or EOC connections?");
+    return false;
+}
+#endif
+//--------------------------------------------------
+#if USE_MAXIMTINYTESTER
+#else // USE_MAXIMTINYTESTER
+#if APPLICATION_MAX5171
+bool SelfTest_Expect_Input_UPO_pin(CmdLine & cmdLine, int expect_UPO_value, const char *expect_description)
+{
+    int actual_UPO_value = -1;
+    for (int retry_count = 0; retry_count < 10; retry_count++) {
+        actual_UPO_value = UPO_pin.read(); // g_MAX5171_device.UPOinputValue();
+        if (actual_UPO_value == expect_UPO_value) {
+            SelfTest_PASS(cmdLine);
+            cmdLine.serial().printf("UPO signal=%d %s", expect_UPO_value, expect_description);
+            return true;
+        }
+        // UPO condition not met, retry for a while until give up
+        wait_ms(100); // delay
+    }
+    cmdLine.serial().printf("\r\n!WARN "); // SelfTest_FAIL(cmdLine);
+    cmdLine.serial().printf("expected UPO signal=%d %s", expect_UPO_value, expect_description);
+    cmdLine.serial().printf(", but got actual UPO=%d", actual_UPO_value);
+    cmdLine.serial().printf(", missing UPO connections?");
+    return false;
+}
+#endif // APPLICATION_MAX5171
+#endif // USE_MAXIMTINYTESTER
+//--------------------------------------------------
+void SelfTest(CmdLine & cmdLine)
+{
+    //--------------------------------------------------
+#if USE_MAXIMTINYTESTER
+#if analogIn4_IS_HIGH_RANGE_OF_analogIn0
+    // Platform board uses AIN4,AIN5,.. as high range of AIN0,AIN1,..
+    // MaximTinyTester(Stream& AssociatedSerialPort, const char *Name);
+    MaximTinyTester tinyTester(cmdLine, analogIn4, analogIn5, analogIn2, analogIn3, analogIn0, analogIn4);
+    tinyTester.analogInPin_fullScaleVoltage[0] = analogInPin_fullScaleVoltage[4]; // board support
+    tinyTester.analogInPin_fullScaleVoltage[1] = analogInPin_fullScaleVoltage[5]; // board support
+    tinyTester.analogInPin_fullScaleVoltage[2] = analogInPin_fullScaleVoltage[2]; // board support
+    tinyTester.analogInPin_fullScaleVoltage[3] = analogInPin_fullScaleVoltage[3]; // board support
+    tinyTester.analogInPin_fullScaleVoltage[4] = analogInPin_fullScaleVoltage[0]; // board support
+    tinyTester.analogInPin_fullScaleVoltage[5] = analogInPin_fullScaleVoltage[1]; // board support
+    // low range channels AIN0, AIN1, AIN2, AIN3
+#else // analogIn4_IS_HIGH_RANGE_OF_analogIn0
+    // Platform board uses simple analog inputs
+    // MaximTinyTester(Stream& AssociatedSerialPort, const char *Name);
+    MaximTinyTester tinyTester(cmdLine, analogIn0, analogIn1, analogIn2, analogIn3, analogIn4, analogIn5);
+    tinyTester.analogInPin_fullScaleVoltage[0] = analogInPin_fullScaleVoltage[0]; // board support
+    tinyTester.analogInPin_fullScaleVoltage[1] = analogInPin_fullScaleVoltage[1]; // board support
+    tinyTester.analogInPin_fullScaleVoltage[2] = analogInPin_fullScaleVoltage[2]; // board support
+    tinyTester.analogInPin_fullScaleVoltage[3] = analogInPin_fullScaleVoltage[3]; // board support
+    tinyTester.analogInPin_fullScaleVoltage[4] = analogInPin_fullScaleVoltage[4]; // board support
+    tinyTester.analogInPin_fullScaleVoltage[5] = analogInPin_fullScaleVoltage[5]; // board support
+#endif
+#else // USE_MAXIMTINYTESTER
+    //--------------------------------------------------
+    g_SelfTest_nPass = 0;
+    g_SelfTest_nFail = 0;
+#endif // USE_MAXIMTINYTESTER
+#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
+#if APPLICATION_MAX5715 // SelfTest
+    //
+    // TODO: tinyTester.FunctionCall_Expect replaces SelfTest_DACCodeOfVoltage_Expect
+#if USE_MAXIMTINYTESTER
+    //
+    // define function under test using C++11 lambda expression [](){}
+    // uint8_t MAX5715::Init(void)
+    uint8_t (*fn_MAX5715_Init)() = [](){ return g_MAX5715_device.Init(); };
+    //
+    // define function under test using C++11 lambda expression [](){}
+    // uint16_t MAX5715::DACCodeOfVoltage(double voltageV)
+    uint16_t (*fn_MAX5715_DACCodeOfVoltage)(double) = [](double voltageV){ return g_MAX5715_device.DACCodeOfVoltage(voltageV); };
+    //
+    // define function under test using C++11 lambda expression [](){}
+    // double MAX5715::VoltageOfCode(uint16_t value_u14)
+    double (*fn_MAX5715_VoltageOfCode)(uint16_t) = [](uint16_t value_u14){ return g_MAX5715_device.VoltageOfCode(value_u14); };
+    //
+    // define function under test using C++11 lambda expression [](){}
+    // void MAX5715::CODEnLOADn(uint8_t channel_0_3, uint16_t dacCodeLsbs)
+    void (*fn_MAX5715_CODEnLOADn)(uint8_t channel_0_3, uint16_t dacCodeLsbs) = [](uint8_t channel_0_3, uint16_t dacCodeLsbs){ return g_MAX5715_device.CODEnLOADn(channel_0_3, dacCodeLsbs); };
+    //
+#else // USE_MAXIMTINYTESTER
+    //
+    // VERIFY: self-test uint16_t MAX5715_DACCodeOfVoltage(double voltageV)
+    // @pre g_MAX5715_device.VRef = Voltage of REF input, in Volts
+    // @param[in] voltage = physical voltage in Volts
+    // @returns raw 12-bit MAX5715 code (right justified).
+    //
+    // VERIFY: self-test double MAX5715_VoltageOfCode(uint16_t value_u12)
+    // @pre g_MAX5715_device.VRef = Voltage of REF input, in Volts
+    // @param[in] value_u12: raw 12-bit MAX5715 code (right justified).
+    // @Returns physical voltage corresponding to MAX5715 code.
+    //
+#endif // USE_MAXIMTINYTESTER
+    //
+    //
+    //
+    //
+    //------------------------------------------------------------
+    g_MAX5715_device.VRef = 4.096;     // MAX5715 12-bit LSB = 0.0010V
+    SelfTest_print_Vref(cmdLine);
+    //~ cmdLine.serial().printf("\r\n");
+    //
+#if USE_MAXIMTINYTESTER
+    // tinyTester.FunctionCall_Expect replaces SelfTest_DACCodeOfVoltage_Expect
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 10.0, 0x0FFF);     // overrange FS
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 4.0950, 0x0FFF);
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 4.0945, 0x0FFF);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 4.0944, 0x0FFE);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 4.0943, 0x0FFE);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 4.0942, 0x0FFE);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 4.0941, 0x0FFE);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 4.0940, 0x0FFE);     // search for code transition
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 4.0939, 0x0FFE);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 4.0938, 0x0FFE);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 4.0937, 0x0FFE);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 4.0936, 0x0FFE);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 4.0935, 0x0FFD);
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 4.0930, 0x0FFD);
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.0480, 0x0800);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.0470, 0x07FF);
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 1.0000, 0x03E8);     // 1.0 volt
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0030, 0x0003);
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0020, 0x0002);
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0010, 0x0001);
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0000, 0x0000);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, -0.0001, 0x0000);     // overrange ZS
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, -0.0002, 0x0000);     // overrange ZS
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, -1.0, 0x0000);     // overrange ZS
+#else // USE_MAXIMTINYTESTER
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 10.0, 0x0FFF);     // overrange FS
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 4.0950, 0x0FFF);
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 4.0945, 0x0FFF);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 4.0944, 0x0FFE);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 4.0943, 0x0FFE);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 4.0942, 0x0FFE);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 4.0941, 0x0FFE);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 4.0940, 0x0FFE);     // search for code transition
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 4.0939, 0x0FFE);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 4.0938, 0x0FFE);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 4.0937, 0x0FFE);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 4.0936, 0x0FFE);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 4.0935, 0x0FFD);
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 4.0930, 0x0FFD);
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.0480, 0x0800);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.0470, 0x07FF);
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 1.0000, 0x03E8);     // 1.0 volt
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0030, 0x0003);
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0020, 0x0002);
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0010, 0x0001);
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0000, 0x0000);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, -0.0001, 0x0000);     // overrange ZS
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, -0.0002, 0x0000);     // overrange ZS
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, -1.0, 0x0000);     // overrange ZS
+#endif // USE_MAXIMTINYTESTER
+    //
+#if USE_MAXIMTINYTESTER
+    // tinyTester.FunctionCall_Expect replaces SelfTest_VoltageOfCode_Expect
+    tinyTester.FunctionCall_Expect("MAX5715.VoltageOfCode", fn_MAX5715_VoltageOfCode, 0x0FFF, 4.0950);
+    tinyTester.FunctionCall_Expect("MAX5715.VoltageOfCode", fn_MAX5715_VoltageOfCode, 0x0FFE, 4.0940);
+    tinyTester.FunctionCall_Expect("MAX5715.VoltageOfCode", fn_MAX5715_VoltageOfCode, 0x0800, 2.0480);
+    tinyTester.FunctionCall_Expect("MAX5715.VoltageOfCode", fn_MAX5715_VoltageOfCode, 0x07FF, 2.0470);
+    tinyTester.FunctionCall_Expect("MAX5715.VoltageOfCode", fn_MAX5715_VoltageOfCode, 0x03E8, 1.0000);     // 1.0 volt
+    tinyTester.FunctionCall_Expect("MAX5715.VoltageOfCode", fn_MAX5715_VoltageOfCode, 0x0001, 0.0010);
+    tinyTester.FunctionCall_Expect("MAX5715.VoltageOfCode", fn_MAX5715_VoltageOfCode, 0x0000, 0.0000);
+#else // USE_MAXIMTINYTESTER
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x0FFF, 4.0950);
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x0FFE, 4.0940);
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x0800, 2.0480);
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x07FF, 2.0470);
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x03E8, 1.0000);     // 1.0 volt
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x0001, 0.0010);
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x0000, 0.0000);
+#endif // USE_MAXIMTINYTESTER
+    //
+    //------------------------------------------------------------
+    cmdLine.serial().printf("\r\n");
+    g_MAX5715_device.VRef = 2.048;     // 12-bit LSB = 0.0005V
+    SelfTest_print_Vref(cmdLine);
+    //~ cmdLine.serial().printf("\r\n");
+#if USE_MAXIMTINYTESTER
+    // tinyTester.FunctionCall_Expect replaces SelfTest_DACCodeOfVoltage_Expect
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 10.0, 0x0FFF);     // overrange FS
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.0480, 0x0FFF);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.0479, 0x0FFF);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.0478, 0x0FFF);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.0477, 0x0FFF);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.0476, 0x0FFF);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.0475, 0x0FFF);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.0474, 0x0FFF);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.0473, 0x0FFF);
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.0472, 0x0FFE);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.0471, 0x0FFE);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.0470, 0x0FFE);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.0469, 0x0FFE);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.0468, 0x0FFE);
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.0467, 0x0FFD);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.0466, 0x0FFD);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.0465, 0x0FFD);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.0464, 0x0FFD);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.0463, 0x0FFD);
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 1.0240, 0x0800);
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 1.0235, 0x07FF);
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 1.0000, 0x07D0);     // 1.0 volt
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0017, 0x0003);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0016, 0x0003);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0015, 0x0003);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0014, 0x0003);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0013, 0x0003);
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0012, 0x0002);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0011, 0x0002);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0010, 0x0002);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0009, 0x0002);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0008, 0x0002);
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0007, 0x0001);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0006, 0x0001);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0005, 0x0001);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0004, 0x0001);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0003, 0x0001);
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0002, 0x0000);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0001, 0x0000);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0000, 0x0000);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, -0.0001, 0x0000);     // overrange ZS
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, -0.0002, 0x0000);     // overrange ZS
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, -1.0, 0x0000);     // overrange ZS
+#else // USE_MAXIMTINYTESTER
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 10.0, 0x0FFF);     // overrange FS
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.0480, 0x0FFF);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.0479, 0x0FFF);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.0478, 0x0FFF);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.0477, 0x0FFF);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.0476, 0x0FFF);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.0475, 0x0FFF);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.0474, 0x0FFF);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.0473, 0x0FFF);
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.0472, 0x0FFE);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.0471, 0x0FFE);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.0470, 0x0FFE);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.0469, 0x0FFE);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.0468, 0x0FFE);
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.0467, 0x0FFD);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.0466, 0x0FFD);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.0465, 0x0FFD);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.0464, 0x0FFD);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.0463, 0x0FFD);
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 1.0240, 0x0800);
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 1.0235, 0x07FF);
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 1.0000, 0x07D0);     // 1.0 volt
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0017, 0x0003);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0016, 0x0003);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0015, 0x0003);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0014, 0x0003);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0013, 0x0003);
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0012, 0x0002);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0011, 0x0002);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0010, 0x0002);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0009, 0x0002);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0008, 0x0002);
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0007, 0x0001);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0006, 0x0001);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0005, 0x0001);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0004, 0x0001);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0003, 0x0001);
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0002, 0x0000);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0001, 0x0000);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0000, 0x0000);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, -0.0001, 0x0000);     // overrange ZS
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, -0.0002, 0x0000);     // overrange ZS
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, -1.0, 0x0000);     // overrange ZS
+#endif // USE_MAXIMTINYTESTER
+#if USE_MAXIMTINYTESTER
+    // tinyTester.FunctionCall_Expect replaces SelfTest_VoltageOfCode_Expect
+    tinyTester.FunctionCall_Expect("MAX5715.VoltageOfCode", fn_MAX5715_VoltageOfCode, 0x0FFF, 2.0475);
+    tinyTester.FunctionCall_Expect("MAX5715.VoltageOfCode", fn_MAX5715_VoltageOfCode, 0x0FFE, 2.0470);
+    tinyTester.FunctionCall_Expect("MAX5715.VoltageOfCode", fn_MAX5715_VoltageOfCode, 0x0FFD, 2.0465);
+    tinyTester.FunctionCall_Expect("MAX5715.VoltageOfCode", fn_MAX5715_VoltageOfCode, 0x0800, 1.0240);
+    tinyTester.FunctionCall_Expect("MAX5715.VoltageOfCode", fn_MAX5715_VoltageOfCode, 0x07FF, 1.0235);
+    tinyTester.FunctionCall_Expect("MAX5715.VoltageOfCode", fn_MAX5715_VoltageOfCode, 0x07D0, 1.0000);     // 1.0 volt
+    tinyTester.FunctionCall_Expect("MAX5715.VoltageOfCode", fn_MAX5715_VoltageOfCode, 0x0002, 0.0010);
+    tinyTester.FunctionCall_Expect("MAX5715.VoltageOfCode", fn_MAX5715_VoltageOfCode, 0x0001, 0.0005);
+    tinyTester.FunctionCall_Expect("MAX5715.VoltageOfCode", fn_MAX5715_VoltageOfCode, 0x0000, 0.0000);
+#else // USE_MAXIMTINYTESTER
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x0FFF, 2.0475);
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x0FFE, 2.0470);
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x0FFD, 2.0465);
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x0800, 1.0240);
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x07FF, 1.0235);
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x07D0, 1.0000);     // 1.0 volt
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x0002, 0.0010);
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x0001, 0.0005);
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x0000, 0.0000);
+#endif // USE_MAXIMTINYTESTER
+    //
+    //
+    //------------------------------------------------------------
+    cmdLine.serial().printf("\r\n");
+    g_MAX5715_device.VRef = 2.500;     // 12-bit LSB = 0.0006105006105006105V
+    SelfTest_print_Vref(cmdLine);
+    //~ cmdLine.serial().printf("\r\n");
+#if USE_MAXIMTINYTESTER
+    // tinyTester.FunctionCall_Expect replaces SelfTest_DACCodeOfVoltage_Expect
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 10.0, 0x0FFF);     // overrange FS
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.5000, 0x0FFF);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4999, 0x0FFF);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4998, 0x0FFF);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4997, 0x0FFF);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4996, 0x0FFF);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4995, 0x0FFF);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4994, 0x0FFF);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4993, 0x0FFF);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4992, 0x0FFF);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4991, 0x0FFF);
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4990, 0x0FFE);     // search for code transitions
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4989, 0x0FFE);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4988, 0x0FFE);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4987, 0x0FFE);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4986, 0x0FFE);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4985, 0x0FFE);
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4984, 0x0FFD);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4983, 0x0FFD);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4982, 0x0FFD);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4981, 0x0FFD);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4980, 0x0FFD);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4979, 0x0FFD);
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4978, 0x0FFC);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4977, 0x0FFC);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4976, 0x0FFC);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4975, 0x0FFC);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4974, 0x0FFC);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4973, 0x0FFC);
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4972, 0x0FFB);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4971, 0x0FFB);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 2.4970, 0x0FFB);
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 1.2500, 0x0800);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 1.2494, 0x07FF);
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 1.0000, 0x0666);     // 1.0 volt
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0019, 0x0003);     // search for code transitions
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0018, 0x0003);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0017, 0x0003);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0016, 0x0003);
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0015, 0x0002);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0014, 0x0002);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0013, 0x0002);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0012, 0x0002);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0011, 0x0002);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0010, 0x0002);
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0009, 0x0001);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0008, 0x0001);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0007, 0x0001);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0006, 0x0001);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0005, 0x0001);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0004, 0x0001);
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0003, 0x0000);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0002, 0x0000);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0001, 0x0000);
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, 0.0000, 0x0000);
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, -0.0001, 0x0000);     // overrange ZS
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, -0.0002, 0x0000);     // overrange ZS
+    tinyTester.FunctionCall_Expect("MAX5715.DACCodeOfVoltage", fn_MAX5715_DACCodeOfVoltage, -1.0, 0x0000);     // overrange ZS
+#else // USE_MAXIMTINYTESTER
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 10.0, 0x0FFF);     // overrange FS
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.5000, 0x0FFF);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4999, 0x0FFF);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4998, 0x0FFF);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4997, 0x0FFF);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4996, 0x0FFF);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4995, 0x0FFF);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4994, 0x0FFF);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4993, 0x0FFF);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4992, 0x0FFF);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4991, 0x0FFF);
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4990, 0x0FFE);     // search for code transitions
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4989, 0x0FFE);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4988, 0x0FFE);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4987, 0x0FFE);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4986, 0x0FFE);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4985, 0x0FFE);
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4984, 0x0FFD);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4983, 0x0FFD);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4982, 0x0FFD);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4981, 0x0FFD);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4980, 0x0FFD);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4979, 0x0FFD);
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4978, 0x0FFC);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4977, 0x0FFC);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4976, 0x0FFC);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4975, 0x0FFC);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4974, 0x0FFC);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4973, 0x0FFC);
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4972, 0x0FFB);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4971, 0x0FFB);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4970, 0x0FFB);
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 1.2500, 0x0800);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 1.2494, 0x07FF);
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 1.0000, 0x0666);     // 1.0 volt
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0019, 0x0003);     // search for code transitions
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0018, 0x0003);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0017, 0x0003);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0016, 0x0003);
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0015, 0x0002);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0014, 0x0002);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0013, 0x0002);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0012, 0x0002);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0011, 0x0002);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0010, 0x0002);
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0009, 0x0001);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0008, 0x0001);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0007, 0x0001);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0006, 0x0001);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0005, 0x0001);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0004, 0x0001);
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0003, 0x0000);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0002, 0x0000);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0001, 0x0000);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.0000, 0x0000);
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, -0.0001, 0x0000);     // overrange ZS
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, -0.0002, 0x0000);     // overrange ZS
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, -1.0, 0x0000);     // overrange ZS
+#endif // USE_MAXIMTINYTESTER
+#if USE_MAXIMTINYTESTER
+    // tinyTester.FunctionCall_Expect replaces SelfTest_VoltageOfCode_Expect
+    tinyTester.FunctionCall_Expect("MAX5715.VoltageOfCode", fn_MAX5715_VoltageOfCode, 0x0FFF, 2.5000);
+    tinyTester.FunctionCall_Expect("MAX5715.VoltageOfCode", fn_MAX5715_VoltageOfCode, 0x0FFE, 2.4988);
+    tinyTester.FunctionCall_Expect("MAX5715.VoltageOfCode", fn_MAX5715_VoltageOfCode, 0x0FFD, 2.4976);
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.VoltageOfCode", fn_MAX5715_VoltageOfCode, 0x0800, 1.2500);
+    tinyTester.FunctionCall_Expect("MAX5715.VoltageOfCode", fn_MAX5715_VoltageOfCode, 0x07FF, 1.2494);
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.VoltageOfCode", fn_MAX5715_VoltageOfCode, 0x0667, 1.0000);     // 1.0 volt
+    tinyTester.FunctionCall_Expect("MAX5715.VoltageOfCode", fn_MAX5715_VoltageOfCode, 0x0666, 1.0000);     // 1.0 volt
+    //
+    tinyTester.FunctionCall_Expect("MAX5715.VoltageOfCode", fn_MAX5715_VoltageOfCode, 0x0002, 0.0012);
+    tinyTester.FunctionCall_Expect("MAX5715.VoltageOfCode", fn_MAX5715_VoltageOfCode, 0x0001, 0.0006);
+    tinyTester.FunctionCall_Expect("MAX5715.VoltageOfCode", fn_MAX5715_VoltageOfCode, 0x0000, 0.0000);
+#else // USE_MAXIMTINYTESTER
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x0FFF, 2.5000);
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x0FFE, 2.4988);
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x0FFD, 2.4976);
+    //
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x0800, 1.2500);
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x07FF, 1.2494);
+    //
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x0667, 1.0000);     // 1.0 volt
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x0666, 1.0000);     // 1.0 volt
+    //
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x0002, 0.0012);
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x0001, 0.0006);
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x0000, 0.0000);
+#endif // USE_MAXIMTINYTESTER
+    //
+    //
+    // Device Testing: DAC commands, verify using on-board ADC inputs
+    //
+    cmdLine.serial().printf("\r\n      MAX5715.Init()");
+    g_MAX5715_device.Init();
+    //
+    uint16_t ch = 0;
+    uint16_t code = 0xfff;
+    double voltageV = 0.5;
+    //
+    // full-scale output on ch0, test MAX5715 internal REF options
+    ch = 0;
+    cmdLine.serial().printf("\r\n      MAX5715.CODEnLOADn ch=%d code=%d", ch, code);
+    g_MAX5715_device.CODEnLOADn(ch, code);
+    //
+    cmdLine.serial().printf("\r\n      MAX5715.REF(MAX5715::REF_AlwaysOn_2V048)");
+    g_MAX5715_device.REF(MAX5715::REF_AlwaysOn_2V048);
+#if USE_MAXIMTINYTESTER
+    // TODO: tinyTester.Wait_Output_Settling replaces wait_ms
+    tinyTester.Wait_Output_Settling();
+    // TODO: tinyTester.AnalogIn0_Read_Expect_voltageV replaces SelfTest_AnalogInput_Expect_ch_V
+    tinyTester.err_threshold = 0.030; // 30mV
+    tinyTester.AnalogIn0_Read_Expect_voltageV(2.048);
+#else // USE_MAXIMTINYTESTER
+    wait_ms(100); // delay
+    SelfTest_AnalogInput_Expect_ch_V(cmdLine, 4, 2.048);
+#endif // USE_MAXIMTINYTESTER
+    //
+    cmdLine.serial().printf("\r\n      MAX5715.REF(MAX5715::REF_AlwaysOn_4V096)");
+    g_MAX5715_device.REF(MAX5715::REF_AlwaysOn_4V096);
+    // MAX32625MBED 4.096V may be as low as 3.3V supply
+#if USE_MAXIMTINYTESTER
+    // TODO: tinyTester.Wait_Output_Settling replaces wait_ms
+    tinyTester.Wait_Output_Settling();
+    // TODO: tinyTester.AnalogIn0_Read_Expect_voltageV replaces SelfTest_AnalogInput_Expect_ch_V
+    tinyTester.err_threshold = 0.50; // 30mV
+    tinyTester.AnalogIn0_Read_Expect_voltageV(3.750); // accept 3.25V to 4.25V
+#else // USE_MAXIMTINYTESTER
+    wait_ms(100); // delay
+    SelfTest_AnalogInput_Expect_ch_V(cmdLine, 4, 3.750, 0.50); // accept 3.25V to 4.25V
+#endif // USE_MAXIMTINYTESTER
+    //
+    cmdLine.serial().printf("\r\n      MAX5715.REF(MAX5715::REF_AlwaysOn_2V500)");
+    g_MAX5715_device.REF(MAX5715::REF_AlwaysOn_2V500);
+#if USE_MAXIMTINYTESTER
+    // TODO: tinyTester.Wait_Output_Settling replaces wait_ms
+    tinyTester.Wait_Output_Settling();
+    // TODO: tinyTester.AnalogIn0_Read_Expect_voltageV replaces SelfTest_AnalogInput_Expect_ch_V
+    tinyTester.err_threshold = 0.030; // 30mV
+    tinyTester.AnalogIn0_Read_Expect_voltageV(2.500);
+#else // USE_MAXIMTINYTESTER
+    wait_ms(100); // delay
+    SelfTest_AnalogInput_Expect_ch_V(cmdLine, 4, 2.500);
+#endif // USE_MAXIMTINYTESTER
+    //
+    // test the individual channel outputs
+    ch = 0;
+    voltageV = 0.5;
+    code = g_MAX5715_device.DACCodeOfVoltage(voltageV);
+    cmdLine.serial().printf("\r\n      MAX5715.CODEnLOADn ch=%d code=%d", ch, code);
+    g_MAX5715_device.CODEnLOADn(ch, code);
+#if USE_MAXIMTINYTESTER
+    // TODO: tinyTester.Wait_Output_Settling replaces wait_ms
+    tinyTester.Wait_Output_Settling();
+    // TODO: tinyTester.AnalogIn0_Read_Expect_voltageV replaces SelfTest_AnalogInput_Expect_ch_V
+    tinyTester.err_threshold = 0.030; // 30mV
+    tinyTester.AnalogIn0_Read_Expect_voltageV(voltageV);
+#else // USE_MAXIMTINYTESTER
+    SelfTest_AnalogInput_Expect_ch_V(cmdLine, ch, voltageV);
+#endif // USE_MAXIMTINYTESTER
+    //
+    ch = 1;
+    voltageV = 0.2;
+    code = g_MAX5715_device.DACCodeOfVoltage(voltageV);
+    cmdLine.serial().printf("\r\n      MAX5715.CODEnLOADn ch=%d code=%d", ch, code);
+    g_MAX5715_device.CODEnLOADn(ch, code);
+#if USE_MAXIMTINYTESTER
+    // TODO: tinyTester.Wait_Output_Settling replaces wait_ms
+    tinyTester.Wait_Output_Settling();
+    // TODO: tinyTester.AnalogIn0_Read_Expect_voltageV replaces SelfTest_AnalogInput_Expect_ch_V
+    tinyTester.err_threshold = 0.030; // 30mV
+    tinyTester.AnalogIn1_Read_Expect_voltageV(voltageV);
+#else // USE_MAXIMTINYTESTER
+    SelfTest_AnalogInput_Expect_ch_V(cmdLine, ch, voltageV);
+#endif // USE_MAXIMTINYTESTER
+    //
+    ch = 2;
+    voltageV = 0.4;
+    code = g_MAX5715_device.DACCodeOfVoltage(voltageV);
+    cmdLine.serial().printf("\r\n      MAX5715.CODEnLOADn ch=%d code=%d", ch, code);
+    g_MAX5715_device.CODEnLOADn(ch, code);
+#if USE_MAXIMTINYTESTER
+    // TODO: tinyTester.Wait_Output_Settling replaces wait_ms
+    tinyTester.Wait_Output_Settling();
+    // TODO: tinyTester.AnalogIn0_Read_Expect_voltageV replaces SelfTest_AnalogInput_Expect_ch_V
+    tinyTester.err_threshold = 0.030; // 30mV
+    tinyTester.AnalogIn2_Read_Expect_voltageV(voltageV);
+#else // USE_MAXIMTINYTESTER
+    SelfTest_AnalogInput_Expect_ch_V(cmdLine, ch, voltageV);
+#endif // USE_MAXIMTINYTESTER
+    //
+    ch = 3;
+    voltageV = 0.25;
+    code = g_MAX5715_device.DACCodeOfVoltage(voltageV);
+    cmdLine.serial().printf("\r\n      MAX5715.CODEnLOADn ch=%d code=%d", ch, code);
+    g_MAX5715_device.CODEnLOADn(ch, code);
+#if USE_MAXIMTINYTESTER
+    // TODO: tinyTester.Wait_Output_Settling replaces wait_ms
+    tinyTester.Wait_Output_Settling();
+    // TODO: tinyTester.AnalogIn0_Read_Expect_voltageV replaces SelfTest_AnalogInput_Expect_ch_V
+    tinyTester.err_threshold = 0.030; // 30mV
+    tinyTester.AnalogIn3_Read_Expect_voltageV(voltageV);
+#else // USE_MAXIMTINYTESTER
+    SelfTest_AnalogInput_Expect_ch_V(cmdLine, ch, voltageV);
+#endif // USE_MAXIMTINYTESTER
+    //
+    // test that the channels are independent
+#if USE_MAXIMTINYTESTER
+    tinyTester.AnalogIn0_Read_Expect_voltageV(g_MAX5715_device.VoltageOfCode(g_MAX5715_device.CODE[0]));
+    tinyTester.AnalogIn1_Read_Expect_voltageV(g_MAX5715_device.VoltageOfCode(g_MAX5715_device.CODE[1]));
+    tinyTester.AnalogIn2_Read_Expect_voltageV(g_MAX5715_device.VoltageOfCode(g_MAX5715_device.CODE[2]));
+    tinyTester.AnalogIn3_Read_Expect_voltageV(g_MAX5715_device.VoltageOfCode(g_MAX5715_device.CODE[3]));
+#else // USE_MAXIMTINYTESTER
+    for (ch = 0; ch < 4; ch++) {
+        voltageV = g_MAX5715_device.VoltageOfCode(g_MAX5715_device.CODE[ch]);
+        SelfTest_AnalogInput_Expect_ch_V(cmdLine, ch, voltageV);
+    }
+#endif // USE_MAXIMTINYTESTER
+    //
+#elif APPLICATION_MAX11131
+    //
+    // MAX11131BOB self-test functions
+    //~ SelfTest_FAIL(cmdLine);
+    //~ cmdLine.serial().printf("test program not implemented yet");
+    int16_t value_u12;
+    int channelId;
+    double voltageV = 0.5;
+    //
+    //cmdLine.serial().printf("\r\n      0.0: MAX11131.Init()");
+    //g_MAX11131_device.Init();
+    //
+    // Device Testing: ADC commands, verify with on-board ADC and SPI framing
+    //
+    // MAX11131 SelfTest: MAX11131 SPI connections (Power Supply and GND, SCLK, MOSI, MISO, CS)
+    cmdLine.serial().printf("\r\n");
+    cmdLine.serial().printf(
+        "\r\n      1.0: Test SCAN_0100_StandardExt -- verify SPI (VDD, GND, SCLK, MOSI, MISO, CS)");
+    cmdLine.serial().printf("\r\n      MAX11131.Init()");
+    g_MAX11131_device.Init();
+    // Send MOSI data       Expect MISO data    Description
+    // 1000_0000_0000_0000  xxxx_xxxx_xxxx_xxxx ADC_CONFIGURATION REFSEL=0 SPM[1:0]=0 ECHO=0
+    // 0010_0111_1010_0100  xxxx_xxxx_xxxx_xxxx ADC_MODE_CONTROL SCAN_0100_StandardExt CHSEL=15 RESET=1 CHANID=1
+    // 0000_0000_0000_0000  0000_xxxx_xxxx_xxxx Channel ID tag = AIN0 expect high nybble 0
+    // 0000_0000_0000_0000  0001_xxxx_xxxx_xxxx Channel ID tag = AIN1 expect high nybble 1
+    // 0000_0000_0000_0000  0010_xxxx_xxxx_xxxx Channel ID tag = AIN2 expect high nybble 2
+    // 0000_0000_0000_0000  0011_xxxx_xxxx_xxxx Channel ID tag = AIN3 expect high nybble 3
+    //
+    cmdLine.serial().printf("\r\n      MOSI <-- 1000_0000_0000_0000  ADC_CONFIGURATION REFSEL=0 SPM[1:0]=0 ECHO=0");
+    g_MAX11131_device.SPIoutputCS(0); // drive CS low
+    g_MAX11131_device.SPIwrite16bits(0x8000);
+    g_MAX11131_device.SPIoutputCS(1); // drive CS high
+    //
+    cmdLine.serial().printf(
+        "\r\n      MOSI <-- 0010_0111_1010_0100  ADC_MODE_CONTROL SCAN_0100_StandardExt CHSEL=15 RESET=1 CHANID=1");
+    g_MAX11131_device.SPIoutputCS(0); // drive CS low
+    g_MAX11131_device.SPIwrite16bits(0x27a4);
+    g_MAX11131_device.SPIoutputCS(1); // drive CS high
+    //
+    for (int channelIndex = 0; channelIndex < 16; channelIndex++) {
+        //~ cmdLine.serial().printf("\r\n      MISO --> expect 0000_xxxx_xxxx_xxxx");
+        g_MAX11131_device.SPIoutputCS(0); // drive CS low
+        g_MAX11131_device.RAW_misoData16[channelIndex] = g_MAX11131_device.SPIread16bits();
+        g_MAX11131_device.SPIoutputCS(1); // drive CS high
+        int expect_channelId = channelIndex;
+        int actual_channelId = (g_MAX11131_device.RAW_misoData16[channelIndex] >> 12) & 0x000F;
+        if (actual_channelId != expect_channelId)
+        {
+            SelfTest_FAIL(cmdLine);
+            cmdLine.serial().printf("MISO --> 0x%4.4x", (g_MAX11131_device.RAW_misoData16[channelIndex] & 0xFFFF));
+            cmdLine.serial().printf(" expect 0x%1.1xxxx (channel ID %d)", expect_channelId, expect_channelId);
+            cmdLine.serial().printf(" but got 0x%1.1xxxx", actual_channelId);
+        }
+        else
+        {
+            SelfTest_PASS(cmdLine);
+            cmdLine.serial().printf("MISO --> 0x%4.4x", (g_MAX11131_device.RAW_misoData16[channelIndex] & 0xFFFF));
+            cmdLine.serial().printf(" expect 0x%1.1xxxx (channel ID %d)", expect_channelId, expect_channelId);
+        }
+    }
+    //
+    // TODO1: MAX11131 SelfTest: MAX11131 Supports Internal Clock Modes (CNVST, EOC)
+    cmdLine.serial().printf("\r\n");
+    cmdLine.serial().printf(
+        "\r\n      1.1: Test SCAN_0011_StandardInt -- verify Internal Clock signals (CNVST, EOC)");
+    cmdLine.serial().printf("\r\n      MAX11131.Init()");
+    g_MAX11131_device.Init();
+    g_MAX11131_device.SPIoutputCS(0); // drive CS low
+    g_MAX11131_device.RAW_misoData16[0] = g_MAX11131_device.SPIread16bits();
+    g_MAX11131_device.SPIoutputCS(1); // drive CS high
+    SelfTest_MAX11131_EOC_expect(cmdLine, 1, "initial value before sending commands"); // TODO1: MAX11131 SelfTest false failure here?
+    // Send MOSI data       Expect MISO data    Description
+    // 1000_0000_0000_0000  xxxx_xxxx_xxxx_xxxx ADC_CONFIGURATION REFSEL=0 SPM[1:0]=0 ECHO=0 No Averaging
+    // 0001_1001_1010_0000  xxxx_xxxx_xxxx_xxxx ADC_MODE_CONTROL SCAN_0011_StandardInt CHSEL=3 RESET=1 SWCNV=0
+    // 0000_0000_0000_0000  0000_xxxx_xxxx_xxxx Channel ID tag = AIN0 expect high nybble 0
+    // 0000_0000_0000_0000  0001_xxxx_xxxx_xxxx Channel ID tag = AIN1 expect high nybble 1
+    // 0000_0000_0000_0000  0010_xxxx_xxxx_xxxx Channel ID tag = AIN2 expect high nybble 2
+    // 0000_0000_0000_0000  0011_xxxx_xxxx_xxxx Channel ID tag = AIN3 expect high nybble 3
+    //
+    cmdLine.serial().printf("\r\n      MOSI <-- 1000_0000_0000_0000  ADC_CONFIGURATION REFSEL=0 SPM[1:0]=0 ECHO=0");
+    g_MAX11131_device.SPIoutputCS(0); // drive CS low
+    g_MAX11131_device.SPIwrite16bits(0x8000);
+    g_MAX11131_device.SPIoutputCS(1); // drive CS high
+    //
+    cmdLine.serial().printf(
+        "\r\n      MOSI <-- 0001_1001_1010_0000  ADC_MODE_CONTROL SCAN_0011_StandardInt CHSEL=3 RESET=1 SWCNV=0");
+    g_MAX11131_device.SPIoutputCS(0); // drive CS low
+    g_MAX11131_device.SPIwrite16bits(0x19a0);
+    g_MAX11131_device.SPIoutputCS(1); // drive CS high
+    //
+    for (int channelIndex = 0; channelIndex < 4; channelIndex++) {
+        //~ cmdLine.serial().printf("\r\n      MISO --> expect 0000_xxxx_xxxx_xxxx");
+        //~ wait_ms(200); // delay
+        g_MAX11131_device.CNVSToutputPulseLow();
+        //~ g_MAX11131_device.CNVSToutputValue(0);
+        //~ wait_ms(100); // delay
+        //~ g_MAX11131_device.CNVSToutputValue(1);
+        // g_MAX11131_device.EOCinputWaitUntilLow(); // infinite wait hazard, need to fail if timeout exceeded
+        SelfTest_MAX11131_EOC_expect(cmdLine, 0, "after CNVST pulse");
+        g_MAX11131_device.SPIoutputCS(0); // drive CS low
+        g_MAX11131_device.RAW_misoData16[channelIndex] = g_MAX11131_device.SPIread16bits();
+        g_MAX11131_device.SPIoutputCS(1); // drive CS high
+        SelfTest_MAX11131_EOC_expect(cmdLine, 1, "after SPI read");
+        int expect_channelId = channelIndex;
+        int actual_channelId = (g_MAX11131_device.RAW_misoData16[channelIndex] >> 12) & 0x000F;
+        if (actual_channelId != expect_channelId)
+        {
+            SelfTest_FAIL(cmdLine);
+            cmdLine.serial().printf("MISO --> 0x%4.4x", (g_MAX11131_device.RAW_misoData16[channelIndex] & 0xFFFF));
+            cmdLine.serial().printf(" expect 0x%1.1xxxx (channel ID %d)", expect_channelId, expect_channelId);
+            cmdLine.serial().printf(" but got 0x%1.1xxxx", actual_channelId);
+        }
+        else
+        {
+            SelfTest_PASS(cmdLine);
+            cmdLine.serial().printf("MISO --> 0x%4.4x", (g_MAX11131_device.RAW_misoData16[channelIndex] & 0xFFFF));
+            cmdLine.serial().printf(" expect 0x%1.1xxxx (channel ID %d)", expect_channelId, expect_channelId);
+        }
+    }
+    //
+    // TODO1: MAX11131 SelfTest: Test Fixture: MAX541ACPA+ to MAX32625MBED.AIN0/AIN4
+    // Test Fixture: MAX541 connected to spi2
+    // SPI spi2_max541(SPI2_MOSI, SPI2_MISO, SPI2_SCK); // mosi, miso, sclk spi2 TARGET_MAX32635MBED: P2_5 P2_6 P2_4 Arduino 2x3-pin header; microSD
+    // DigitalOut spi2_max541_cs(SPI2_SS); // TARGET_MAX32635MBED: P2_7 Arduino 2x3-pin header
+    // Test Fixture: MAX541 spi2 init
+    cmdLine.serial().printf("\r\n");
+    cmdLine.serial().printf("\r\n      2.0: Test Fixture: MAX541 connected to spi2 (P2.4 P2.5 P2.7)?");
+    bool SelfTest_has_max541 = false;
+    // Check actual MAX541 reference voltage
+    cmdLine.serial().printf("\r\n      Test Fixture: MAX541 midscale voltage measure with MAX32625MBED AIN0/4");
+    max541.Set_Code(0x8000); // we don't know the fullscale voltage yet, so set code to midscale
+    double max541_midscale_V = analogInPin_fullScaleVoltage[4] * analogIn4.read(); // TARGET_MAX32630 J1.5 AIN_4 = AIN0 / 5.0     fullscale is 6.0V
+    const int average_count = 100;
+    const double average_K = 0.25;
+    for (int count = 0; count < average_count; count++) {
+        double measurement_V = analogInPin_fullScaleVoltage[4] * analogIn4.read(); // TARGET_MAX32630 J1.5 AIN_4 = AIN0 / 5.0     fullscale is 6.0V
+        max541_midscale_V = ((1 - average_K) * max541_midscale_V) + (average_K * measurement_V);
+    }
+    if (max541_midscale_V > 1.0f) {
+        max541.VRef = 2.0 * max541_midscale_V;
+        cmdLine.serial().printf("\r\n      Test Fixture: MAX541 midscale = %1.3fV, so fullscale = %1.3fV",
+                                max541_midscale_V, max541.VRef);
+        // Detect whether MAX541 is really connected to MAX32625MBED.AIN0/AIN4
+        voltageV = 1.0f;
+        SelfTest_has_max541 = SelfTest_MAX541_Voltage(cmdLine, max541, voltageV);
+    }
+    if (SelfTest_has_max541) {
+        voltageV = 0.0f;
+        SelfTest_has_max541 = SelfTest_MAX541_Voltage(cmdLine, max541, voltageV);
+    }
+    if (SelfTest_has_max541) {
+        voltageV = 3.0f;
+        SelfTest_has_max541 = SelfTest_MAX541_Voltage(cmdLine, max541, voltageV);
+    }
+    if (SelfTest_has_max541) {
+        voltageV = 1.65f;
+        SelfTest_has_max541 = SelfTest_MAX541_Voltage(cmdLine, max541, voltageV);
+    }
+    if (SelfTest_has_max541) {
+        voltageV = 2.0f;
+        SelfTest_has_max541 = SelfTest_MAX541_Voltage(cmdLine, max541, voltageV);
+    }
+    if (SelfTest_has_max541) {
+        voltageV = 0.25f;
+        SelfTest_has_max541 = SelfTest_MAX541_Voltage(cmdLine, max541, voltageV);
+    }
+    if (SelfTest_has_max541) {
+        voltageV = 0.5f;
+        SelfTest_has_max541 = SelfTest_MAX541_Voltage(cmdLine, max541, voltageV);
+    }
+    if (SelfTest_has_max541) {
+        voltageV = 1.0f;
+        SelfTest_has_max541 = SelfTest_MAX541_Voltage(cmdLine, max541, voltageV);
+    }
+    if (SelfTest_has_max541 == false) {
+        // don't fail just because we're missing the test fixture...
+        cmdLine.serial().printf("\r\n      Test Fixture: MAX541 not present");
+        //~ g_SelfTest_nFail--;
+    }
+    //
+    // TODO1: MAX11131 SelfTest: if Test Fixture: drive MAX541, compare MAX32625MBED.AIN0/AIN4 and MAX11131 AIN0
+    // indirectly verify the reference voltage by reading a known input voltage
+    if (SelfTest_has_max541) {
+        cmdLine.serial().printf("\r\n");
+        cmdLine.serial().printf("\r\n      2.1: TODO1: Check MAX11131 reference voltage using SCAN_0001_Manual");
+        voltageV = 1.0f;
+        SelfTest_MAX541_Voltage(cmdLine, max541, voltageV);
+        cmdLine.serial().printf("\r\n      MAX11131.Init()");
+        g_MAX11131_device.Init();
+        // 1 ScanManual ch=0 pm=0 id=1
+        g_MAX11131_device.channelNumber_0_15 = 0;
+        g_MAX11131_device.PowerManagement_0_2 = 0;
+        g_MAX11131_device.chan_id_0_1 = 1;
+        cmdLine.serial().printf("\r\n      MAX11131.channelNumber_0_15=%d", g_MAX11131_device.channelNumber_0_15);
+        cmdLine.serial().printf("\r\n      MAX11131.PowerManagement_0_2=%d", g_MAX11131_device.PowerManagement_0_2);
+        cmdLine.serial().printf("\r\n      MAX11131.chan_id_0_1=%d", g_MAX11131_device.chan_id_0_1);
+        g_MAX11131_device.NumWords = g_MAX11131_device.ScanManual();
+        cmdLine.serial().printf("\r\n      MAX11131.ScanManual -- NumWords = %d",
+                                g_MAX11131_device.NumWords);
+        g_MAX11131_device.NumWords = g_MAX11131_device.ScanManual();
+        g_MAX11131_device.ReadAINcode();
+        cmdLine.serial().printf("\r\n      MAX11131.ReadAINcode");
+        AINcode_print_value_externalClock(cmdLine, g_MAX11131_device.NumWords);
+        //
+        //  2.1: TODO1: Check MAX11131 reference voltage -- why we read 0xffff 2.4999V here?
+        //
+        cmdLine.serial().printf("\r\n      MAX11131.ScanManual -- NumWords = %d",
+                                g_MAX11131_device.NumWords);
+        // Read raw ADC codes from device into AINcode[] and RAW_misoData16[]
+        // @pre one of the MAX11311_Scan functions was called, setting g_MAX11131_device.NumWords
+        g_MAX11131_device.ReadAINcode();
+        cmdLine.serial().printf("\r\n      MAX11131.ReadAINcode");
+        AINcode_print_value_externalClock(cmdLine, g_MAX11131_device.NumWords);
+        //
+        //  2.1: TODO1: Check MAX11131 reference voltage -- why we read 0xffff 2.4999V here?
+        //
+        // compare with mbed/Arduino AIN0-AIN3
+        // MAX32625MBED.AIN4 = MAX11131.AIN0
+        channelId = 0;
+        value_u12 = g_MAX11131_device.AINcode[channelId];
+        voltageV = g_MAX11131_device.VoltageOfCode(value_u12, channelId);
+        SelfTest_AnalogInput_Expect_ch_V(cmdLine, 4, voltageV, 0.100);
+    }
+    //
+    if (SelfTest_has_max541) {
+        voltageV = 1.0f;
+        SelfTest_MAX541_Voltage(cmdLine, max541, voltageV);
+    }
+    cmdLine.serial().printf("\r\n");
+    cmdLine.serial().printf("\r\n      3.1: Test SCAN_0001_Manual");
+    cmdLine.serial().printf("\r\n      MAX11131.Init()");
+    g_MAX11131_device.Init();
+    // 1 ScanManual ch=0 pm=0 id=1
+    g_MAX11131_device.channelNumber_0_15 = 0;
+    g_MAX11131_device.PowerManagement_0_2 = 0;
+    g_MAX11131_device.chan_id_0_1 = 1;
+    cmdLine.serial().printf("\r\n      MAX11131.channelNumber_0_15=%d", g_MAX11131_device.channelNumber_0_15);
+    cmdLine.serial().printf("\r\n      MAX11131.PowerManagement_0_2=%d", g_MAX11131_device.PowerManagement_0_2);
+    cmdLine.serial().printf("\r\n      MAX11131.chan_id_0_1=%d", g_MAX11131_device.chan_id_0_1);
+    g_MAX11131_device.NumWords = g_MAX11131_device.ScanManual();
+    cmdLine.serial().printf("\r\n      MAX11131.ScanManual -- NumWords = %d",
+                            g_MAX11131_device.NumWords);
+    // Read raw ADC codes from device into AINcode[] and RAW_misoData16[]
+    // @pre one of the MAX11311_Scan functions was called, setting g_MAX11131_device.NumWords
+    g_MAX11131_device.ReadAINcode();
+    cmdLine.serial().printf("\r\n      MAX11131.ReadAINcode");
+    AINcode_print_value_externalClock(cmdLine, g_MAX11131_device.NumWords);
+    // compare with mbed/Arduino AIN0-AIN3
+    // MAX32625MBED.AIN4 = MAX11131.AIN0
+    channelId = 0;
+    value_u12 = g_MAX11131_device.AINcode[channelId];
+    voltageV = g_MAX11131_device.VoltageOfCode(value_u12, channelId);
+    SelfTest_AnalogInput_Expect_ch_V(cmdLine, 4, voltageV, 0.100);
+    //
+    cmdLine.serial().printf("\r\n");
+    cmdLine.serial().printf("\r\n      3.4: Test SCAN_0100_StandardExternalClock");
+    cmdLine.serial().printf("\r\n      MAX11131.Init()");
+    g_MAX11131_device.Init();
+    // MAX11131 > 4
+    // ScanStandardExternalClock ch=9 pm=0 id=1
+    // ScanRead_nWords_chanID nWords=10
+    //  ch=0 xu=2964 = 0x0b94 = 1.8091V
+    //  ch=1 xu=2227 = 0x08b3 = 1.3593V
+    //  ch=2 xu=1570 = 0x0622 = 0.9583V
+    //  ch=3 xu=865 = 0x0361 = 0.5280V
+    //  ch=4 xu=630 = 0x0276 = 0.3845V
+    //  ch=5 xu=594 = 0x0252 = 0.3625V
+    //  ch=6 xu=461 = 0x01cd = 0.2814V
+    //  ch=7 xu=364 = 0x016c = 0.2222V
+    //  ch=8 xu=480 = 0x01e0 = 0.2930V
+    //  ch=9 xu=616 = 0x0268 = 0.3760V
+    g_MAX11131_device.channelNumber_0_15 = 9;
+    g_MAX11131_device.PowerManagement_0_2 = 0;
+    g_MAX11131_device.chan_id_0_1 = 1;
+    cmdLine.serial().printf("\r\n      MAX11131.channelNumber_0_15=%d", g_MAX11131_device.channelNumber_0_15);
+    cmdLine.serial().printf("\r\n      MAX11131.PowerManagement_0_2=%d", g_MAX11131_device.PowerManagement_0_2);
+    cmdLine.serial().printf("\r\n      MAX11131.chan_id_0_1=%d", g_MAX11131_device.chan_id_0_1);
+    g_MAX11131_device.NumWords = g_MAX11131_device.ScanStandardExternalClock();
+    cmdLine.serial().printf("\r\n      MAX11131.ScanStandardExternalClock -- NumWords = %d",
+                            g_MAX11131_device.NumWords);
+    // Read raw ADC codes from device into AINcode[] and RAW_misoData16[]
+    // @pre one of the MAX11311_Scan functions was called, setting g_MAX11131_device.NumWords
+    g_MAX11131_device.ReadAINcode();
+    cmdLine.serial().printf("\r\n      MAX11131.ReadAINcode");
+    // @post RAW_misoData16[index] contains the raw SPI Master-In,Slave-Out data
+    // @post AINcode[NUM_CHANNELS] contains the latest readings in LSBs
+    // TODO: expect g_MAX11131_device.NumWords == g_MAX11131_device.channelNumber_0_15 + 1;
+    // TODO: expect RAW_misoData16[index] msnybble 0,1,2,3,...
+    AINcode_print_value_externalClock(cmdLine, g_MAX11131_device.NumWords);
+    // TODO: compare with mbed/Arduino AIN0-AIN3
+    // MAX32625MBED.AIN4 = MAX11131.AIN0
+    channelId = 0;
+    value_u12 = g_MAX11131_device.AINcode[channelId];
+    voltageV = g_MAX11131_device.VoltageOfCode(value_u12, channelId);
+    SelfTest_AnalogInput_Expect_ch_V(cmdLine, 4, voltageV, 0.100);
+    // TODO: compare MAX32625MBED.AIN5 = MAX11131.AIN1
+    //channelId = 1;
+    //value_u12 = g_MAX11131_device.AINcode[channelId];
+    //voltageV = g_MAX11131_device.VoltageOfCode(value_u12, channelId);
+    //SelfTest_AnalogInput_Expect_ch_V(cmdLine, 5, voltageV, 0.100);
+    //
+#elif APPLICATION_MAX5171
+
+#if USE_MAXIMTINYTESTER
+    // TODO: tinyTester.FunctionCall_Expect replaces SelfTest_DACCodeOfVoltage_Expect
+    //
+    // define function under test using C++11 lambda expression [](){}
+    // uint8_t MAX5171::Init(void)
+    uint8_t (*fn_MAX5171_Init)() = [](){ return g_MAX5171_device.Init(); };
+    //
+    // define function under test using C++11 lambda expression [](){}
+    // uint16_t MAX5171::DACCodeOfVoltage(double voltageV)
+    uint16_t (*fn_MAX5171_DACCodeOfVoltage)(double) = [](double voltageV){ return g_MAX5171_device.DACCodeOfVoltage(voltageV); };
+    //
+    // define function under test using C++11 lambda expression [](){}
+    // double MAX5171::VoltageOfCode(uint16_t value_u14)
+    double (*fn_MAX5171_VoltageOfCode)(uint16_t) = [](uint16_t value_u14){ return g_MAX5171_device.VoltageOfCode(value_u14); };
+    //
+    // define function under test using C++11 lambda expression [](){}
+    // uint8_t MAX5171::CODE_LOAD(uint16_t dacCodeLsbs)
+    uint8_t (*fn_MAX5171_CODE_LOAD)(uint16_t dacCodeLsbs) = [](uint16_t dacCodeLsbs){ return g_MAX5171_device.CODE_LOAD(dacCodeLsbs); };
+    //
+    //double one_LSB = (g_MAX5171_device.VRef / 16383); // 14-bit DAC FS
+    tinyTester.err_threshold = (g_MAX5171_device.VRef / 16383); // 14-bit DAC FS
+    // TODO: tinyTester.Wait_Output_Settling replaces wait_ms
+    tinyTester.settle_time_msec = 250;
+#else // USE_MAXIMTINYTESTER
+#endif // USE_MAXIMTINYTESTER
+
+    g_MAX5171_device.VRef = 2.500;     // MAX5171 14-bit LSB = 0.00015V
+    SelfTest_print_Vref(cmdLine);
+    //
+#if USE_MAXIMTINYTESTER
+    // TODO: tinyTester.FunctionCall_Expect replaces SelfTest_DACCodeOfVoltage_Expect
+    tinyTester.FunctionCall_Expect("MAX5171.DACCodeOfVoltage", fn_MAX5171_DACCodeOfVoltage, 2.499847412109375, 0x3FFF);
+    tinyTester.FunctionCall_Expect("MAX5171.DACCodeOfVoltage", fn_MAX5171_DACCodeOfVoltage, 2.49969482421875, 0x3FFE);
+    tinyTester.FunctionCall_Expect("MAX5171.DACCodeOfVoltage", fn_MAX5171_DACCodeOfVoltage, 2.499542236328125, 0x3FFD);
+    tinyTester.FunctionCall_Expect("MAX5171.DACCodeOfVoltage", fn_MAX5171_DACCodeOfVoltage, 2.4993896484375, 0x3FFC);
+    //
+    tinyTester.FunctionCall_Expect("MAX5171.DACCodeOfVoltage", fn_MAX5171_DACCodeOfVoltage, 1.250152587890625, 0x2001);
+    tinyTester.FunctionCall_Expect("MAX5171.DACCodeOfVoltage", fn_MAX5171_DACCodeOfVoltage, 1.25, 0x2000);
+    tinyTester.FunctionCall_Expect("MAX5171.DACCodeOfVoltage", fn_MAX5171_DACCodeOfVoltage, 1.249847412109375, 0x1FFF);
+    tinyTester.FunctionCall_Expect("MAX5171.DACCodeOfVoltage", fn_MAX5171_DACCodeOfVoltage, 1.24969482421875, 0x1FFE);
+    //
+    tinyTester.FunctionCall_Expect("MAX5171.DACCodeOfVoltage", fn_MAX5171_DACCodeOfVoltage, 0.000457763671875, 0x0003);
+    tinyTester.FunctionCall_Expect("MAX5171.DACCodeOfVoltage", fn_MAX5171_DACCodeOfVoltage, 0.00030517578125, 0x0002);
+    tinyTester.FunctionCall_Expect("MAX5171.DACCodeOfVoltage", fn_MAX5171_DACCodeOfVoltage, 0.000152587890625, 0x0001);
+    tinyTester.FunctionCall_Expect("MAX5171.DACCodeOfVoltage", fn_MAX5171_DACCodeOfVoltage, 0.00000, 0x0000);
+#else // USE_MAXIMTINYTESTER
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.499847412109375, 0x3FFF);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.49969482421875, 0x3FFE);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.499542236328125, 0x3FFD);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 2.4993896484375, 0x3FFC);
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 1.250152587890625, 0x2001);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 1.25, 0x2000);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 1.249847412109375, 0x1FFF);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 1.24969482421875, 0x1FFE);
+    //
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.000457763671875, 0x0003);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.00030517578125, 0x0002);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.000152587890625, 0x0001);
+    SelfTest_DACCodeOfVoltage_Expect(cmdLine, 0.00000, 0x0000);
+#endif // USE_MAXIMTINYTESTER
+    //
+#if USE_MAXIMTINYTESTER
+    // TODO: tinyTester.FunctionCall_Expect replaces SelfTest_VoltageOfCode_Expect
+    tinyTester.FunctionCall_Expect("MAX5171.VoltageOfCode", fn_MAX5171_VoltageOfCode, 0x3FFF, 2.499847412109375);
+    tinyTester.FunctionCall_Expect("MAX5171.VoltageOfCode", fn_MAX5171_VoltageOfCode, 0x3FFE, 2.49969482421875);
+    tinyTester.FunctionCall_Expect("MAX5171.VoltageOfCode", fn_MAX5171_VoltageOfCode, 0x3FFD, 2.499542236328125);
+    tinyTester.FunctionCall_Expect("MAX5171.VoltageOfCode", fn_MAX5171_VoltageOfCode, 0x3FFC, 2.4993896484375);
+    //
+    tinyTester.FunctionCall_Expect("MAX5171.VoltageOfCode", fn_MAX5171_VoltageOfCode, 0x2001, 1.250152587890625);
+    tinyTester.FunctionCall_Expect("MAX5171.VoltageOfCode", fn_MAX5171_VoltageOfCode, 0x2000, 1.25);
+    tinyTester.FunctionCall_Expect("MAX5171.VoltageOfCode", fn_MAX5171_VoltageOfCode, 0x1FFF, 1.249847412109375);
+    tinyTester.FunctionCall_Expect("MAX5171.VoltageOfCode", fn_MAX5171_VoltageOfCode, 0x1FFE, 1.24969482421875);
+    //
+    tinyTester.FunctionCall_Expect("MAX5171.VoltageOfCode", fn_MAX5171_VoltageOfCode, 0x0003, 0.000457763671875);
+    tinyTester.FunctionCall_Expect("MAX5171.VoltageOfCode", fn_MAX5171_VoltageOfCode, 0x0002, 0.00030517578125);
+    tinyTester.FunctionCall_Expect("MAX5171.VoltageOfCode", fn_MAX5171_VoltageOfCode, 0x0001, 0.000152587890625);
+    tinyTester.FunctionCall_Expect("MAX5171.VoltageOfCode", fn_MAX5171_VoltageOfCode, 0x0000, 0.00000);
+#else // USE_MAXIMTINYTESTER
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x3FFF, 2.499847412109375);
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x3FFE, 2.49969482421875);
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x3FFD, 2.499542236328125);
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x3FFC, 2.4993896484375);
+    //
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x2001, 1.250152587890625);
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x2000, 1.25);
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x1FFF, 1.249847412109375);
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x1FFE, 1.24969482421875);
+    //
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x0003, 0.000457763671875);
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x0002, 0.00030517578125);
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x0001, 0.000152587890625);
+    SelfTest_VoltageOfCode_Expect(cmdLine, 0x0000, 0.00000);
+#endif // USE_MAXIMTINYTESTER
+    //
+    // Device Testing: DAC commands, verify using on-board ADC inputs
+    //
+    cmdLine.serial().printf("\r\n      MAX5171.Init()");
+    g_MAX5171_device.Init();
+    //
+    tinyTester.err_threshold = 0.030; // 30mV
+    uint16_t code = 0x3FFF;
+    //~ double voltageV = 0.5;
+    //
+    cmdLine.serial().printf("\r\n      MAX5171.CODE_LOAD code=%d", code);
+    g_MAX5171_device.CODE_LOAD(code);
+#if USE_MAXIMTINYTESTER
+    // TODO: tinyTester.Wait_Output_Settling replaces wait_ms
+    tinyTester.Wait_Output_Settling();
+    // TODO: tinyTester.AnalogIn0_Read_Expect_voltageV replaces SelfTest_AnalogInput_Expect_ch_V
+    tinyTester.AnalogIn0_Read_Expect_voltageV(2.500);
+#else // USE_MAXIMTINYTESTER
+    wait_ms(250); // delay
+#if analogIn4_IS_HIGH_RANGE_OF_analogIn0
+    // Platform board uses AIN4,AIN5,.. as high range of AIN0,AIN1,..
+    // low range channels AIN0, AIN1, AIN2, AIN3
+    SelfTest_AnalogInput_Expect_ch_V(cmdLine, 4, 2.500);
+#else // analogIn4_IS_HIGH_RANGE_OF_analogIn0
+    // Platform board uses simple analog inputs
+    SelfTest_AnalogInput_Expect_ch_V(cmdLine, 0, 2.500);
+#endif
+#endif // USE_MAXIMTINYTESTER
+    //
+    code = 0x0000;
+    cmdLine.serial().printf("\r\n      MAX5171.CODE_LOAD code=%d", code);
+    g_MAX5171_device.CODE_LOAD(code);
+#if USE_MAXIMTINYTESTER
+    // TODO: tinyTester.Wait_Output_Settling replaces wait_ms
+    tinyTester.Wait_Output_Settling();
+    // TODO: tinyTester.AnalogIn0_Read_Expect_voltageV replaces SelfTest_AnalogInput_Expect_ch_V
+    tinyTester.AnalogIn0_Read_Expect_voltageV(0.0000);
+#else // USE_MAXIMTINYTESTER
+    wait_ms(250); // delay
+#if analogIn4_IS_HIGH_RANGE_OF_analogIn0
+    // Platform board uses AIN4,AIN5,.. as high range of AIN0,AIN1,..
+    // low range channels AIN0, AIN1, AIN2, AIN3
+    SelfTest_AnalogInput_Expect_ch_V(cmdLine, 4, 0.0000);
+#else // analogIn4_IS_HIGH_RANGE_OF_analogIn0
+    // Platform board uses simple analog inputs
+    SelfTest_AnalogInput_Expect_ch_V(cmdLine, 0, 0.0000);
+#endif
+#endif // USE_MAXIMTINYTESTER
+    //
+    code = 0x1FFF;
+    cmdLine.serial().printf("\r\n      MAX5171.CODE_LOAD code=%d", code);
+    g_MAX5171_device.CODE_LOAD(code);
+#if USE_MAXIMTINYTESTER
+    // TODO: tinyTester.Wait_Output_Settling replaces wait_ms
+    tinyTester.Wait_Output_Settling();
+    // TODO: tinyTester.AnalogIn0_Read_Expect_voltageV replaces SelfTest_AnalogInput_Expect_ch_V
+    tinyTester.AnalogIn0_Read_Expect_voltageV(1.2500);
+#else // USE_MAXIMTINYTESTER
+    wait_ms(250); // delay
+#if analogIn4_IS_HIGH_RANGE_OF_analogIn0
+    // Platform board uses AIN4,AIN5,.. as high range of AIN0,AIN1,..
+    // low range channels AIN0, AIN1, AIN2, AIN3
+    SelfTest_AnalogInput_Expect_ch_V(cmdLine, 4, 1.2500);
+#else // analogIn4_IS_HIGH_RANGE_OF_analogIn0
+    // Platform board uses simple analog inputs
+    SelfTest_AnalogInput_Expect_ch_V(cmdLine, 0, 1.2500);
+#endif
+#endif // USE_MAXIMTINYTESTER
+    //
+    // test UPO User Programmable Output, verify using digital input D2
+    //
+    cmdLine.serial().printf("\r\n      MAX5171.UPO_HIGH");
+    g_MAX5171_device.UPO_HIGH();
+#if USE_MAXIMTINYTESTER
+    tinyTester.Wait_Output_Settling();
+    // TODO: tinyTester.DigitalIn_Read_Expect_WarnOnly replaces SelfTest_Expect_Input_UPO_pin
+    tinyTester.DigitalIn_Read_Expect_WarnOnly(UPO_pin, "UPO", 1, "UPO_pin is high after MAX5171 UPO_HIGH command");
+#else // USE_MAXIMTINYTESTER
+    wait_ms(100); // delay
+    SelfTest_Expect_Input_UPO_pin(cmdLine, 1, "UPO_pin is high after MAX5171 UPO_HIGH command");
+#endif // USE_MAXIMTINYTESTER
+    //
+    cmdLine.serial().printf("\r\n      MAX5171.UPO_LOW");
+    g_MAX5171_device.UPO_LOW();
+#if USE_MAXIMTINYTESTER
+    tinyTester.Wait_Output_Settling();
+    // TODO: tinyTester.DigitalIn_Read_Expect_WarnOnly replaces SelfTest_Expect_Input_UPO_pin
+    tinyTester.DigitalIn_Read_Expect_WarnOnly(UPO_pin, "UPO", 0, "UPO_pin is low after MAX5171 UPO_LOW command");
+#else // USE_MAXIMTINYTESTER
+    wait_ms(100); // delay
+    SelfTest_Expect_Input_UPO_pin(cmdLine, 0, "UPO_pin is low after MAX5171 UPO_LOW command");
+#endif // USE_MAXIMTINYTESTER
+    //
+    cmdLine.serial().printf("\r\n      MAX5171.UPO_HIGH");
+    g_MAX5171_device.UPO_HIGH();
+#if USE_MAXIMTINYTESTER
+    tinyTester.Wait_Output_Settling(); // wait_ms(100); // delay
+    // TODO: tinyTester.DigitalIn_Read_Expect_WarnOnly replaces SelfTest_Expect_Input_UPO_pin
+    tinyTester.DigitalIn_Read_Expect_WarnOnly(UPO_pin, "UPO", 1, "UPO_pin is high after MAX5171 UPO_HIGH command");
+#else // USE_MAXIMTINYTESTER
+    wait_ms(100); // delay
+    SelfTest_Expect_Input_UPO_pin(cmdLine, 1, "UPO_pin is high after MAX5171 UPO_HIGH command");
+#endif // USE_MAXIMTINYTESTER
+    //
+#elif APPLICATION_MAX11410
+    //
+    // TODO: placeholder for self-test functions
+    SelfTest_FAIL(cmdLine);
+    cmdLine.serial().printf("test program not implemented yet");
+    //
+#elif APPLICATION_MAX12345
+    //
+    // TODO: placeholder for self-test functions
+    SelfTest_FAIL(cmdLine);
+    cmdLine.serial().printf("test program not implemented yet");
+    //
+#else // APPLICATION_MAX5715
+      // TODO: placeholder for self-test functions
+#endif // APPLICATION_MAX5715
+       //
+#if 0
+    // Test of the pass/fail report mechanism
+    SelfTest_FAIL(cmdLine);
+    cmdLine.serial().printf("injecting one false failure for test reporting");
+#endif
+    //
+    // Report number of pass and number of fail test results
+#if USE_MAXIMTINYTESTER
+    tinyTester.Report_Summary();
+#if USE_LEDS
+    if (tinyTester.nFail == 0) {
+        rgb_led.green();     // diagnostic rbg led GREEN
+    }
+    else {
+        rgb_led.red(); // diagnostic rbg led RED
+    }
+#endif // USE_LEDS
+#else // USE_MAXIMTINYTESTER
+    cmdLine.serial().printf("\r\nSummary: %d PASS %d FAIL\r\n", g_SelfTest_nPass, g_SelfTest_nFail);
+    //~ cmdLine.serial().printf(g_SelfTest_nPass);
+    //~ cmdLine.serial().printf(" PASS ");
+    //~ cmdLine.serial().printf(g_SelfTest_nFail);
+    //~ cmdLine.serial().printf(" FAIL\r\n");
+    if (g_SelfTest_nFail == 0) {
+#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
+    }
+#endif // USE_MAXIMTINYTESTER
+}
+
+
+//--------------------------------------------------
+void main_menu_status(CmdLine & cmdLine)
+{
+    cmdLine.serial().printf("\r\nMain menu");
+#if APPLICATION_MAX5715 // main_menu_status banner
+    cmdLine.serial().printf(" MAX5715 12-bit 4-ch SPI VOUT DAC");
+#elif APPLICATION_MAX11131 // main_menu_status banner
+    cmdLine.serial().printf(" MAX11131 12-bit 3MSps 16-ch ADC");
+#elif APPLICATION_MAX5171 // main_menu_status banner
+    cmdLine.serial().printf(" MAX5171 14-bit Force/Sense VOUT DAC");
+#elif APPLICATION_MAX11410 // main_menu_status banner
+    cmdLine.serial().printf(" MAX11410 24-bit 1.9ksps Delta-Sigma ADC");
+#elif APPLICATION_MAX12345 // main_menu_status banner
+    cmdLine.serial().printf(" MAX12345");
+#else
+    //cmdLine.serial().printf(" ");
+#endif
+    cmdLine.serial().printf(" %s", TARGET_NAME);
+    if (cmdLine.nameStr())
+    {
+        cmdLine.serial().printf(" [%s]", cmdLine.nameStr());
+    }
+#if USE_COMMAND_BUFFER
+    //cmdLine.serial().printf(" [USE_COMMAND_BUFFER]");
+#endif
+#if HAS_BUTTON1_DEMO_INTERRUPT
+    cmdLine.serial().printf(" [Button1=DemoConfig1]");
+#endif
+#if HAS_BUTTON2_DEMO_INTERRUPT
+    cmdLine.serial().printf(" [Button2=DemoConfig2]");
+#endif
+#if HAS_BUTTON1_DEMO
+    // print BUTTON1 status
+    cmdLine.serial().printf("\r\n BUTTON1 = %d", button1.read());
+#endif
+#if HAS_BUTTON2_DEMO
+    // print BUTTON1 status
+    cmdLine.serial().printf("\r\n BUTTON2 = %d", button2.read());
+#endif
+    cmdLine.serial().printf("\r\n ? -- help");
+}
+
+//--------------------------------------------------
+void main_menu_help(CmdLine & cmdLine)
+{
+    // ? -- help
+    //~ cmdLine.serial().printf("\r\nMenu:");
+    cmdLine.serial().printf("\r\n # -- lines beginning with # are comments");
+    cmdLine.serial().printf("\r\n . -- SelfTest");
+    //cmdLine.serial().printf("\r\n ! -- Initial Configuration");
+    //
+    // % standardize diagnostic commands
+    // %Hpin -- digital output high
+    // %Lpin -- digital output low
+    // %?pin -- digital input
+    // %A %Apin -- analog input
+    // %Ppin df=xx -- pwm output
+    // %Wpin -- measure high pulsewidth input in usec
+    // %wpin -- measure low pulsewidth input in usec
+    // %I... -- I2C diagnostics
+    // %IP -- I2C probe
+    // %IC scl=100khz ADDR=? -- I2C configure
+    // %IW ADDR=? cmd=? data,data,data -- write
+    // %IR ADDR=? RD=? -- read
+    // %I^ cmd=? -- i2c_smbus_read_word_data
+    // %S... -- SPI diagnostics
+    // %SC sclk=1Mhz -- SPI configure
+    // %SW -- write (write and read)
+    // %SR -- read (alias for %SW because SPI always write and read)
+    // A-Z,a-z,0-9 reserved for application use
+    //
+#if HAS_digitalInOuts
+    // %Hpin -- digital output high
+    // %Lpin -- digital output low
+    // %?pin -- digital input
+    cmdLine.serial().printf("\r\n %%Hn {pin:");
+    list_digitalInOutPins(cmdLine.serial());
+    cmdLine.serial().printf("} -- High Output");
+    cmdLine.serial().printf("\r\n %%Ln {pin:");
+    list_digitalInOutPins(cmdLine.serial());
+    cmdLine.serial().printf("} -- Low Output");
+    cmdLine.serial().printf("\r\n %%?n {pin:");
+    list_digitalInOutPins(cmdLine.serial());
+    cmdLine.serial().printf("} -- Input");
+#endif
+
+#if HAS_analogIns
+    // Menu A) analogRead A0..7
+    // %A %Apin -- analog input
+    // analogRead(pinIndex) // analog input pins A0, A1, A2, A3, A4, A5; float voltage = analogRead(A0) * (5.0 / 1023.0)
+    cmdLine.serial().printf("\r\n %%A -- analogRead");
+#endif
+
+#if HAS_SPI2_MAX541
+    // TODO1: MAX541 max541(spi2_max541, spi2_max541_cs);
+    cmdLine.serial().printf("\r\n %%D -- DAC output MAX541 (SPI2)");
+#endif
+
+#if HAS_pwmDrivers
+    // Menu P) PWM D3|5|6|9|10|11, Output 0..255
+    // %Ppin df=xx -- pwm output
+    cmdLine.serial().printf("\r\n %%P {High|Low|.|>|<|S|F} 0..255, {pin: *");
+    // analogWrite(analogOutPin, outputValue_0_255) // PWM digital output 0..255: analogWrite works on digital pins 3, 5, 6, 9, 10, and 11. Frequency is 490 Hz except pins 5 and 6 are 980 Hz.
+    //cmdLine.serial().printf("\r\n P) pwmDriver {High|Low|.|>|<|S|F} {pin: *");
+    list_pwmDriverPins(cmdLine.serial());
+    cmdLine.serial().printf("} -- PWM Output");
+#endif
+
+#if HAS_I2C // SUPPORT_I2C
+    // TODO: support I2C HAS_I2C // SUPPORT_I2C
+    // VERIFY: I2C utility commands SUPPORT_I2C
+    // VERIFY: report g_I2C_SCL_Hz = (F_CPU / ((TWBR * 2) + 16)) from last Wire_Sr.setClock(I2C_SCL_Hz);
+    // %I... -- I2C diagnostics
+    // %IP -- I2C probe
+    // %IC scl=100khz ADDR=? -- I2C configure
+    // %IW byte byte ... byte RD=? ADDR=0x -- write
+    // %IR ADDR=? RD=? -- read
+    // %I^ cmd=? -- i2c_smbus_read_word_data
+    //g_I2C_SCL_Hz = (F_CPU / ((TWBR * 2) + 16));   // 'F_CPU' 'TWBR' not declared in this scope
+    cmdLine.serial().printf("\r\n %%IC ADDR=0x%2.2x=(0x%2.2x>>1) SCL=%d=%1.3fkHz -- I2C config",
+                            g_I2C_deviceAddress7, (g_I2C_deviceAddress7 << 1), g_I2C_SCL_Hz,
+                            (g_I2C_SCL_Hz / 1000.));
+    cmdLine.serial().printf("\r\n %%IW byte byte ... byte RD=? ADDR=0x%2.2x -- I2C write/read",
+                            g_I2C_deviceAddress7);
+    //
+#if SUPPORT_I2C
+    // Menu ^ cmd=?) i2c_smbus_read_word_data
+    cmdLine.serial().printf("\r\n %%I^ cmd=? -- i2c_smbus_read_word_data");
+    // test low-level I2C i2c_smbus_read_word_data
+#endif // SUPPORT_I2C
+    //cmdLine.serial().printf(" H) Hunt for attached I2C devices");
+    cmdLine.serial().printf("\r\n %%IP -- I2C Probe for attached devices");
+    // cmdLine.serial().printf(" s) search i2c address");
+#endif // SUPPORT_I2C
+
+#if HAS_SPI // SUPPORT_SPI
+    // TODO: support SPI HAS_SPI // SUPPORT_SPI
+    // SPI test command  S (mosiData)+
+    // %S... -- SPI diagnostics
+    // %SC sclk=1Mhz -- SPI configure
+    // %SW -- write (write and read)
+    // %SR -- read (alias for %SW because SPI always write and read)
+    // spi.format(8,0); // int bits_must_be_8, int mode=0_3 CPOL=0,CPHA=0 rising edge (initial default)
+    // spi.format(8,1); // int bits_must_be_8, int mode=0_3 CPOL=0,CPHA=1 falling edge (initial default)
+    // spi.format(8,2); // int bits_must_be_8, int mode=0_3 CPOL=1,CPHA=0 falling edge (initial default)
+    // spi.format(8,3); // int bits_must_be_8, int mode=0_3 CPOL=1,CPHA=1 rising edge (initial default)
+    // spi.frequency(1000000); // int SCLK_Hz=1000000 = 1MHz (initial default)
+    // mode | POL PHA
+    // -----+--------
+    //   0  |  0   0
+    //   1  |  0   1
+    //   2  |  1   0
+    //   3  |  1   1
+    //cmdLine.serial().printf(" S) SPI mosi,mosi,...mosi hex bytes SCLK=1000000 CPOL=0 CPHA=0");
+    // fixed: mbed-os-5.11: [Warning] format '%d' expects argument of type 'int', but argument 3 has type 'uint32_t {aka long unsigned int}' [-Wformat=]
+    cmdLine.serial().printf("\r\n %%SC SCLK=%ld=%1.3fMHz CPOL=%d CPHA=%d -- SPI config",
+                            g_SPI_SCLK_Hz, (g_SPI_SCLK_Hz / 1000000.),
+                            ((g_SPI_dataMode & SPI_MODE2) ? 1 : 0),
+                            ((g_SPI_dataMode & SPI_MODE1) ? 1 : 0));
+    cmdLine.serial().printf("\r\n %%SW mosi,mosi,...mosi -- SPI write hex bytes");
+    // VERIFY: parse new SPI settings parse_strCommandArgs() SCLK=1000000 CPOL=0 CPHA=0
+#endif // SUPPORT_SPI
+       //
+       // Application-specific commands (help text) here
+       //
+#if APPLICATION_ArduinoPinsMonitor
+# if APPLICATION_MAX5715 // main_menu_help
+# elif APPLICATION_MAX11131 // main_menu_help
+# elif APPLICATION_MAX5171 // main_menu_help
+# elif APPLICATION_MAX11410 // main_menu_help
+# elif APPLICATION_MAX12345 // main_menu_help
+# else
+    cmdLine.serial().printf("\r\n A-Z,a-z,0-9 -- reserved for application use");     // ArduinoPinsMonitor
+# endif
+#endif // APPLICATION_ArduinoPinsMonitor
+       //
+#if APPLICATION_MAX5715 // main_menu_help
+    cmdLine.serial().printf("\r\n 0 ch=? code=? -- CODEn");
+    cmdLine.serial().printf("\r\n 1 ch=? -- LOADn");
+    cmdLine.serial().printf("\r\n 2 ch=? code=? -- CODEnLOADall");
+    cmdLine.serial().printf("\r\n 3 ch=? code=? -- CODEnLOADn");
+    cmdLine.serial().printf("\r\n 40 ch=? -- POWERn_Normal");
+    cmdLine.serial().printf("\r\n 41 ch=? -- POWERn_PD1k");
+    cmdLine.serial().printf("\r\n 42 ch=? -- POWERn_PD100k");
+    cmdLine.serial().printf("\r\n 43 ch=? -- POWERn_PDHiZ");
+    cmdLine.serial().printf("\r\n 50 -- SW_CLEAR");
+    cmdLine.serial().printf("\r\n 51 -- SW_RESET");
+    cmdLine.serial().printf("\r\n 60 ch=? -- CONFIGn_LATCHED");
+    cmdLine.serial().printf("\r\n 61 ch=? -- CONFIGn_TRANSPARENT");
+    cmdLine.serial().printf("\r\n 68 -- CONFIGall_LATCHED");
+    cmdLine.serial().printf("\r\n 69 -- CONFIGall_TRANSPARENT");
+    cmdLine.serial().printf("\r\n 70 -- REF_EXT");
+    cmdLine.serial().printf("\r\n 71 -- REF_2V500");
+    cmdLine.serial().printf("\r\n 72 -- REF_2V048");
+    cmdLine.serial().printf("\r\n 73 -- REF_4V096");
+    cmdLine.serial().printf("\r\n 74 -- REF_AlwaysOn_EXT");
+    cmdLine.serial().printf("\r\n 75 -- REF_AlwaysOn_2V500");
+    cmdLine.serial().printf("\r\n 76 -- REF_AlwaysOn_2V048");
+    cmdLine.serial().printf("\r\n 77 -- REF_AlwaysOn_4V096");
+    cmdLine.serial().printf("\r\n 80 code=? -- CODEall");
+    cmdLine.serial().printf("\r\n 81 -- LOADall");
+    cmdLine.serial().printf("\r\n 82 code=? -- CODEallLOADall");
+    //cmdLine.serial().printf("\r\n 83 code=? -- CODEallLOADall");
+    //
+    // Menu @ -- print device configuration
+    cmdLine.serial().printf("\r\n @ -- print MAX5715 configuration");
+    //
+    // MAX5717 menu function to drive MAX5717_LDACb_Pin LDAC#
+    // Note: '~' is not recommended for menu commands, interferes with ssh
+    cmdLine.serial().printf("\r\n L -- LDAC# pulse LH high LL low");
+    // MAX5717 menu function to drive MAX5717_CLRb_Pin CLR#
+    cmdLine.serial().printf("\r\n C -- CLR# pulse CH high CL low");
+#endif // APPLICATION_MAX5715
+       //
+#if APPLICATION_MAX11131 // main_menu_help
+    // VERIFY: console menu command 0 int16_t MAX11131_ScanRead(void);
+    cmdLine.serial().printf("\r\n 0 n=?                                  -- MAX11131_ScanRead");
+    // VERIFY: console menu command 1 MAX11131_ScanManual(int channelNumber_0_15, int PowerManagement_0_2, int chan_id_0_1);
+    cmdLine.serial().printf("\r\n 1 ch=? pm=? id=?                       -- MAX11131_ScanManual");
+    // VERIFY: console menu command 2 int MAX11131_ScanRepeat(uint8_t channelNumber_0_15, uint8_t average_0_4_8_16_32, uint8_t nscan_4_8_12_16, uint8_t PowerManagement_0_2, uint8_t swcnv_0_1);
+    cmdLine.serial().printf("\r\n 2 ch=? av=? n=? pm=? swcnv=?           -- MAX11131_ScanRepeat");
+    // VERIFY: console menu command 3 MAX11131_ScanStandardInternalClock(int channelNumber_0_15, int average_0_4_8_16_32, int PowerManagement_0_2, int swcnv_0_1);
+    cmdLine.serial().printf("\r\n 3 ch=? av=? pm=? swcnv=?               -- MAX11131_ScanStandardIntClock");
+    // VERIFY: console menu command 4 MAX11131_ScanStandardExternalClock(int channelNumber_0_15, int PowerManagement_0_2, int chan_id_0_1);
+    cmdLine.serial().printf("\r\n 4 ch=? pm=? id=?                       -- MAX11131_ScanStandardExtClock");
+    // VERIFY: console menu command 5 MAX11131_ScanUpperInternalClock(int channelNumber_0_15, int average_0_4_8_16_32, int PowerManagement_0_2, int swcnv_0_1);
+    cmdLine.serial().printf("\r\n 5 ch=? av=? pm=? swcnv=?               -- MAX11131_ScanUpperIntClock");
+    // VERIFY: console menu command 6 MAX11131_ScanUpperExternalClock(int channelNumber_0_15, int PowerManagement_0_2, int chan_id_0_1);
+    cmdLine.serial().printf("\r\n 6 ch=? pm=? id=?                       -- MAX11131_ScanUpperExtClock");
+    // VERIFY: console menu command 7 MAX11131_ScanCustomInternalClock(int16_t enabledChannelsMask, int average_0_4_8_16_32, int PowerManagement_0_2, int swcnv_0_1);
+    cmdLine.serial().printf("\r\n 7 enableMask=0xffff av=? pm=? swcnv=?  -- MAX11131_ScanCustomIntClock");
+    // VERIFY: console menu command 8 MAX11131_ScanCustomExternalClock(int16_t enabledChannelsMask, int PowerManagement_0_2, int chan_id_0_1);
+    cmdLine.serial().printf("\r\n 8 enableMask=0xffff pm=0 id=1          -- MAX11131_ScanCustomExtClock");
+    // VERIFY: console menu command 9 MAX11131_ScanSampleSetExternalClock(uint8_t enabledChannelsPatternLength_1_256, int16_t enabledChannelsPattern[], int PowerManagement_0_2, int chan_id_0_1);
+    cmdLine.serial().printf("\r\n 9 channelsPattern... pm=? id=? | len=? -- MAX11131_ScanSampleSetExtClock");
+    cmdLine.serial().printf("\r\n @                                      -- print MAX11131 configuration");
+    cmdLine.serial().printf("\r\n ISc) IUc) IBc) IRc) reconfigure channel single-ended/unipolar/bipolar/range");
+    // cmdLine.serial().printf("\r\n & -- MAX11131_Example_ScanManual");
+    // Note: '~' is not recommended for menu commands, interferes with ssh
+#endif // APPLICATION_MAX11131
+       //
+#if APPLICATION_MAX5171 // main_menu_help
+    // TODO1: MAX5171 main_menu_help
+    cmdLine.serial().printf("\r\n 0 code=? -- CODE");
+    cmdLine.serial().printf("\r\n 4 code=? -- CODE_LOAD");
+    cmdLine.serial().printf("\r\n 8 -- LOAD");
+    cmdLine.serial().printf("\r\n c -- NOP");
+    cmdLine.serial().printf("\r\n d -- SHUTDOWN");
+    cmdLine.serial().printf("\r\n e0 -- UPO_LOW");
+    cmdLine.serial().printf("\r\n e8 -- UPO_HIGH");
+    cmdLine.serial().printf("\r\n f0 -- MODE1_DOUT_SCLK_RISING_EDGE");
+    cmdLine.serial().printf("\r\n f8 -- MODE0_DOUT_SCLK_FALLING_EDGE");
+    // Note: '~' is not recommended for menu commands, interferes with ssh
+#endif // APPLICATION_MAX5171
+       //
+#if APPLICATION_MAX11410 // main_menu_help
+    // TODO1: MAX11410 main_menu_help
+    cmdLine.serial().printf("\r\n w reg=? data=? -- write register");
+    cmdLine.serial().printf("\r\n r reg=? -- read register");
+    cmdLine.serial().printf("\r\n TC -- thermocouple config");
+    cmdLine.serial().printf("\r\n T -- RTD measurement");
+    cmdLine.serial().printf("\r\n RC -- thermocouple config");
+    cmdLine.serial().printf("\r\n R -- RTD measurement");
+    // Note: '~' is not recommended for menu commands, interferes with ssh
+#endif // APPLICATION_MAX11410
+       //
+#if APPLICATION_MAX12345 // main_menu_help
+    cmdLine.serial().printf("\r\n 0 -- something");
+    cmdLine.serial().printf("\r\n 1 -- something");
+    cmdLine.serial().printf("\r\n 2 -- something");
+    cmdLine.serial().printf("\r\n A -- something");
+    cmdLine.serial().printf("\r\n B -- something");
+    cmdLine.serial().printf("\r\n C -- something");
+    // Note: '~' is not recommended for menu commands, interferes with ssh
+#endif // APPLICATION_MAX12345
+       //
+}
+
+//--------------------------------------------------
+// main menu command-line parser
+// invoked by CmdLine::append(char ch) or CmdLine::idleAppendIfReadable()
+#if USE_COMMAND_BUFFER
+void main_menu_onEOLcommandParser(CmdLine & cmdLine)
+{
+    // DIAGNOSTIC: print line buffer
+    //~ cmdLine.serial().printf("\r\nmain_menu_onEOLcommandParser: ~%s~\r\n", cmdLine.str());
+    //
+    switch (cmdLine[0])
+    {
+        case '?':
+            main_menu_status(cmdLine);
+            main_menu_help(cmdLine);
+            // print command prompt
+            //cmdLine.serial().printf("\r\n>");
+            break;
+        case '\r': case '\n':     // ignore blank line
+        case '\0':     // ignore empty line
+        case '#':     // ignore comment line
+            // # -- lines beginning with # are comments
+            main_menu_status(cmdLine);
+            //~ main_menu_help(cmdLine);
+            // print command prompt
+            //cmdLine.serial().printf("\r\n>");
+            break;
+#if ECHO_EOF_ON_EOL
+        case '\x04':     // Unicode (U+0004) EOT END OF TRANSMISSION = CTRL+D as EOF end of file
+            cmdLine.serial().printf("\x04");     // immediately echo EOF for test scripting
+            diagnostic_led_EOF();
+            break;
+        case '\x1a':     // Unicode (U+001A) SUB SUBSTITUTE = CTRL+Z as EOF end of file
+            cmdLine.serial().printf("\x1a");     // immediately echo EOF for test scripting
+            diagnostic_led_EOF();
+            break;
+#endif
+#if APPLICATION_ArduinoPinsMonitor
+        case '.':
+        {
+            // . -- SelfTest
+            cmdLine.serial().printf("SelfTest()");
+            SelfTest(cmdLine);
+        }
+        break;
+        case '%':
+        {
+            // TODO: consolidate "Arduino Pins Monitor" under '%' submenu -- APPLICATION_ArduinoPinsMonitor
+            // % standardize diagnostic commands
+            // %Hpin -- digital output high
+            // %Lpin -- digital output low
+            // %?pin -- digital input
+            // %A %Apin -- analog input
+            // %Ppin df=xx -- pwm output
+            // %Wpin -- measure high pulsewidth input in usec
+            // %wpin -- measure low pulsewidth input in usec
+            // %I... -- I2C diagnostics
+            // %IP -- I2C probe
+            // %IC scl=100khz ADDR=? -- I2C configure
+            // %IW byte byte ... byte RD=? ADDR=0x -- write
+            // %IR ADDR=? RD=? -- read
+            // %I^ cmd=? -- i2c_smbus_read_word_data
+            // %S... -- SPI diagnostics
+            // %SC sclk=1Mhz -- SPI configure
+            // %SW -- write (write and read)
+            // %SR -- read (alias for %SW because SPI always write and read)
+            // A-Z,a-z,0-9 reserved for application use
+            //
+            // get pinIndex from cmdLine[2]
+            //int pinIndex = cmdLine[2];
+            // *** warning: pointer of type 'void *' used in arithmetic [-Wpointer-arith]
+            //int pinIndex = strtoul((char *)((void *)(cmdLine.str()) + 2), NULL, 10); // strtol(str, NULL, 10): get decimal value
+            //                                                        ^
+            char strPinIndex[3];
+            strPinIndex[0] = cmdLine[2];
+            strPinIndex[1] = cmdLine[3];
+            strPinIndex[2] = '\0';
+            int pinIndex = strtoul(strPinIndex, NULL, 10);         // strtol(str, NULL, 10): get decimal value
+            //cmdLine.serial().printf(" pinIndex=%d ", pinIndex);
+            //
+            // get next character
+            switch (cmdLine[1])
+            {
+#if HAS_digitalInOuts
+                case 'H': case 'h':
+                {
+                    // %Hpin -- digital output high
+#if ARDUINO_STYLE
+                    pinMode(pinIndex, OUTPUT);             // digital pins 0, 1, 2, .. 13, analog input pins A0, A1, .. A5
+                    digitalWrite(pinIndex, HIGH);             // digital pins 0, 1, 2, .. 13, analog input pins A0, A1, .. A5
+#else
+                    DigitalInOut& digitalInOutPin = find_digitalInOutPin(pinIndex);
+                    digitalInOutPin.output();
+                    digitalInOutPin.write(1);
+#endif
+                    cmdLine.serial().printf(" digitalInOutPin %d Output High ", pinIndex);
+                }
+                break;
+                case 'L': case 'l':
+                {
+                    // %Lpin -- digital output low
+#if ARDUINO_STYLE
+                    pinMode(pinIndex, OUTPUT);             // digital pins 0, 1, 2, .. 13, analog input pins A0, A1, .. A5
+                    digitalWrite(pinIndex, LOW);             // digital pins 0, 1, 2, .. 13, analog input pins A0, A1, .. A5
+#else
+                    DigitalInOut& digitalInOutPin = find_digitalInOutPin(pinIndex);
+                    digitalInOutPin.output();
+                    digitalInOutPin.write(0);
+#endif
+                    cmdLine.serial().printf(" digitalInOutPin %d Output Low ", pinIndex);
+                }
+                break;
+                case '?':
+                {
+                    // %?pin -- digital input
+#if ARDUINO_STYLE
+                    pinMode(pinIndex, INPUT);             // digital pins 0, 1, 2, .. 13, analog input pins A0, A1, .. A5
+#else
+                    DigitalInOut& digitalInOutPin = find_digitalInOutPin(pinIndex);
+                    digitalInOutPin.input();
+#endif
+                    microUSBserial.printf(" digitalInOutPin %d Input ", pinIndex);
+#if ARDUINO_STYLE
+                    int value = digitalRead(pinIndex);
+#else
+                    int value = digitalInOutPin.read();
+#endif
+                    cmdLine.serial().printf("%d ", value);
+                }
+                break;
+#endif
+                //
+#if HAS_analogIns
+                case 'A': case 'a':
+                {
+                    // %A %Apin -- analog input
+#if analogIn4_IS_HIGH_RANGE_OF_analogIn0
+                    // Platform board uses AIN4,AIN5,.. as high range of AIN0,AIN1,..
+                    for (int pinIndex = 0; pinIndex < 2; pinIndex++)
+                    {
+                        int cPinIndex = '0' + pinIndex;
+                        AnalogIn& analogInPin = find_analogInPin(cPinIndex);
+                        float adc_full_scale_voltage = analogInPin_fullScaleVoltage[pinIndex];
+                        float normValue_0_1 = analogInPin.read();
+                        //
+                        int pinIndexH = pinIndex + 4;
+                        int cPinIndexH = '0' + pinIndexH;
+                        AnalogIn& analogInPinH = find_analogInPin(cPinIndexH);
+                        float adc_full_scale_voltageH = analogInPin_fullScaleVoltage[pinIndexH];
+                        float normValueH_0_1 = analogInPinH.read();
+                        //
+                        cmdLine.serial().printf("AIN%c = %7.3f%% = %1.3fV  AIN%c = %7.3f%% = %1.3fV  \r\n",
+                                                cPinIndex,
+                                                normValue_0_1 * 100.0,
+                                                normValue_0_1 * adc_full_scale_voltage,
+                                                cPinIndexH,
+                                                normValueH_0_1 * 100.0,
+                                                normValueH_0_1 * adc_full_scale_voltageH
+                                                );
+                    }
+                    for (int pinIndex = 2; pinIndex < 4; pinIndex++)
+                    {
+                        int cPinIndex = '0' + pinIndex;
+                        AnalogIn& analogInPin = find_analogInPin(cPinIndex);
+                        float adc_full_scale_voltage = analogInPin_fullScaleVoltage[pinIndex];
+                        float normValue_0_1 = analogInPin.read();
+                        //
+                        cmdLine.serial().printf("AIN%c = %7.3f%% = %1.3fV\r\n",
+                                                cPinIndex,
+                                                normValue_0_1 * 100.0,
+                                                normValue_0_1 * adc_full_scale_voltage
+                                                );
+                    }
+#else // analogIn4_IS_HIGH_RANGE_OF_analogIn0
+                    // Platform board uses simple analog inputs
+                    // assume standard Arduino analog inputs A0-A5
+                    for (int pinIndex = 0; pinIndex < 6; pinIndex++)
+                    {
+                        int cPinIndex = '0' + pinIndex;
+                        AnalogIn& analogInPin = find_analogInPin(cPinIndex);
+                        float adc_full_scale_voltage = analogInPin_fullScaleVoltage[pinIndex];
+                        float normValue_0_1 = analogInPin.read();
+                        //
+                        cmdLine.serial().printf("AIN%c = %7.3f%% = %1.3fV\r\n",
+                                                cPinIndex,
+                                                normValue_0_1 * 100.0,
+                                                normValue_0_1 * adc_full_scale_voltage
+                                                );
+                    }
+#endif // analogIn4_IS_HIGH_RANGE_OF_analogIn0
+                }
+                break;
+#endif
+                //
+#if HAS_SPI2_MAX541
+                case 'D': case 'd':
+                {
+                    // %D -- DAC output MAX541 (SPI2) -- need cmdLine.parse_float(voltageV)
+                    // MAX541 max541(spi2_max541, spi2_max541_cs);
+                    float voltageV = max541.Get_Voltage();
+                    // if (cmdLine[2] == '+') {
+                    //     // %D+
+                    //     voltageV = voltageV * 1.25f;
+                    //     if (voltageV >= max541.VRef) voltageV = max541.VRef;
+                    //     SelfTest_MAX541_Voltage(cmdLine, max541, voltageV);
+                    // }
+                    // else if (cmdLine[2] == '-') {
+                    //     // %D-
+                    //     voltageV = voltageV * 0.75f;
+                    //     if (voltageV < 0.1f) voltageV = 0.1f;
+                    //     SelfTest_MAX541_Voltage(cmdLine, max541, voltageV);
+                    // }
+                    if (cmdLine.parse_float("V", voltageV))
+                    {
+                        // %D V=1.234 -- set voltage
+                        max541.Set_Voltage(voltageV);
+                    }
+                    else if (cmdLine.parse_float("TEST", voltageV))
+                    {
+                        // %D TEST=1.234 -- set voltage and compare with AIN0
+                        SelfTest_MAX541_Voltage(cmdLine, max541, voltageV);
+                    }
+                    else if (cmdLine.parse_float("CAL", voltageV))
+                    {
+                        // %D CAL=1.234 -- calibrate VRef and compare with AIN0
+
+                        max541.Set_Code(0x8000); // we don't know the fullscale voltage yet, so set code to midscale
+                        double max541_midscale_V = analogInPin_fullScaleVoltage[4] * analogIn4.read(); // TARGET_MAX32630 J1.5 AIN_4 = AIN0 / 5.0     fullscale is 6.0V
+                        const int average_count = 100;
+                        const double average_K = 0.25;
+                        for (int count = 0; count < average_count; count++) {
+                            double measurement_V = analogInPin_fullScaleVoltage[4] * analogIn4.read(); // TARGET_MAX32630 J1.5 AIN_4 = AIN0 / 5.0     fullscale is 6.0V
+                            max541_midscale_V = ((1 - average_K) * max541_midscale_V) + (average_K * measurement_V);
+                        }
+                        max541.VRef = 2.0 * max541_midscale_V;
+                        cmdLine.serial().printf(
+                            "\r\n      MAX541 midscale = %1.3fV, so fullscale = %1.3fV",
+                            max541_midscale_V, max541.VRef);
+                        // Detect whether MAX541 is really connected to MAX32625MBED.AIN0/AIN4
+                        voltageV = 1.0f;
+                        SelfTest_MAX541_Voltage(cmdLine, max541, voltageV);
+                    }
+                    else {
+                        // %D -- print MAX541 DAC status
+                        cmdLine.serial().printf("MAX541 code=0x%4.4x = %1.3fV  VRef=%1.3fV\r\n",
+                                                max541.Get_Code(), max541.Get_Voltage(), max541.VRef);
+                    }
+                }
+                break;
+#endif
+
+                //
+#if HAS_pwmDrivers
+                case 'P': case 'p':
+                {
+                    // %Ppin df=xx -- pwm output
+                }
+                break;
+#endif
+                //
+#if 0 // HAS_pwmDrivers
+                case 'W':
+                case 'w':
+                    // %Wpin -- measure high pulsewidth input in usec
+                    // %wpin -- measure low pulsewidth input in usec
+                    break;
+#endif
+                //
+#if HAS_I2C // SUPPORT_I2C
+                case 'I': case 'i':
+                    // %I... -- I2C diagnostics
+                    // %IP -- I2C probe
+                    // %IC scl=100khz ADDR=? -- I2C configure
+                    // %IW byte byte ... byte RD=? ADDR=0x -- write
+                    // %IR ADDR=? RD=? -- read
+                    // %I^ cmd=? -- i2c_smbus_read_word_data
+                    // get next character
+                    // TODO: parse cmdLine arg (ADDR=\d+)? --> g_I2C_deviceAddress7
+                    cmdLine.parse_byte_hex("ADDR", g_I2C_deviceAddress7);
+                    // TODO: parse cmdLine arg (RD=\d)? --> g_I2C_read_count
+                    g_I2C_read_count = 0;         // read count must be reset every command
+                    cmdLine.parse_byte_dec("RD", g_I2C_read_count);
+                    // TODO: parse cmdLine arg (CMD=\d)? --> g_I2C_command_regAddress
+                    cmdLine.parse_byte_hex("CMD", g_I2C_command_regAddress);
+                    switch (cmdLine[2])
+                    {
+                        case 'P': case 'p':
+                        {
+                            // %IP -- I2C probe
+                            HuntAttachedI2CDevices(cmdLine, 0x03, 0x77);
+                        }
+                        break;
+                        case 'C': case 'c':
+                        {
+                            bool isUpdatedI2CConfig = false;
+                            // %IC scl=100khz ADDR=? -- I2C configure
+                            // parse cmdLine arg (SCL=\d+(kHZ|MHZ)?)? --> g_I2C_SCL_Hz
+                            if (cmdLine.parse_frequency_Hz("SCL", g_I2C_SCL_Hz))
+                            {
+                                isUpdatedI2CConfig = true;
+                                // TODO1: validate g_I2C_SCL_Hz against system clock frequency F_CPU
+                                if (g_I2C_SCL_Hz > limit_max_I2C_SCL_Hz)
+                                {
+                                    g_I2C_SCL_Hz = limit_max_I2C_SCL_Hz;
+                                }
+                                if (g_I2C_SCL_Hz < limit_min_I2C_SCL_Hz)
+                                {
+                                    g_I2C_SCL_Hz = limit_min_I2C_SCL_Hz;
+                                }
+                            }
+                            if (isUpdatedI2CConfig)
+                            {
+                                // declare in narrower scope: MAX32625MBED I2C i2cMaster(...)
+                                I2C i2cMaster(I2C0_SDA, I2C0_SCL);             // sda scl TARGET_MAX32635MBED: P1_6, P1_7 Arduino 10-pin header
+                                i2cMaster.frequency(g_I2C_SCL_Hz);
+                                i2cMaster.start();
+                                i2cMaster.stop();
+                                i2cMaster.frequency(g_I2C_SCL_Hz);
+                                cmdLine.serial().printf(
+                                    "\r\n %%IC ADDR=0x%2.2x=(0x%2.2x>>1) SCL=%d=%1.3fkHz -- I2C config",
+                                    g_I2C_deviceAddress7, (g_I2C_deviceAddress7 << 1), g_I2C_SCL_Hz,
+                                    (g_I2C_SCL_Hz / 1000.));
+                                i2cMaster.start();
+                                i2cMaster.stop();
+                            }
+                        }
+                        break;
+                        case 'W': case 'w':
+                        {
+                            // declare in narrower scope: MAX32625MBED I2C i2cMaster(...)
+                            I2C i2cMaster(I2C0_SDA, I2C0_SCL);             // sda scl TARGET_MAX32635MBED: P1_6, P1_7 Arduino 10-pin header
+                            i2cMaster.frequency(g_I2C_SCL_Hz);
+                            // %IW byte byte ... byte RD=? ADDR=0x -- write
+                            // parse cmdLine byte list --> int byteCount; int mosiData[MAX_SPI_BYTE_COUNT];
+                            #define MAX_I2C_BYTE_COUNT 32
+                            size_t byteCount = byteCount;
+                            static char mosiData[MAX_I2C_BYTE_COUNT];
+                            static char misoData[MAX_I2C_BYTE_COUNT];
+                            if (cmdLine.parse_byteCount_byteList_hex(byteCount, mosiData,
+                                                                     MAX_I2C_BYTE_COUNT))
+                            {
+                                // hex dump mosiData[0..byteCount-1]
+                                cmdLine.serial().printf(
+                                    "\r\nADDR=0x%2.2x=(0x%2.2x>>1) byteCount:%d RD=%d\r\nI2C MOSI->",
+                                    g_I2C_deviceAddress7,
+                                    (g_I2C_deviceAddress7 << 1), byteCount, g_I2C_read_count);
+                                for (unsigned int byteIndex = 0; byteIndex < byteCount; byteIndex++)
+                                {
+                                    cmdLine.serial().printf(" 0x%2.2X", mosiData[byteIndex]);
+                                }
+                                //
+                                // TODO: i2c transfer
+                                //const int addr7bit = 0x48;      // 7 bit I2C address
+                                //const int addr8bit = 0x48 << 1; // 8bit I2C address, 0x90
+                                // /* int  */   i2cMaster.read (int addr8bit, char *data, int length, bool repeated=false) // Read from an I2C slave.
+                                // /* int  */   i2cMaster.read (int ack) // Read a single byte from the I2C bus.
+                                // /* int  */   i2cMaster.write (int addr8bit, const char *data, int length, bool repeated=false) // Write to an I2C slave.
+                                // /* int  */   i2cMaster.write (int data) // Write single byte out on the I2C bus.
+                                // /* void */   i2cMaster.start (void) // Creates a start condition on the I2C bus.
+                                // /* void */   i2cMaster.stop (void) // Creates a stop condition on the I2C bus.
+                                // /* int */    i2cMaster.transfer (int addr8bit, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length, const event_callback_t &callback, int event=I2C_EVENT_TRANSFER_COMPLETE, bool repeated=false) // Start nonblocking I2C transfer. More...
+                                // /* void */   i2cMaster.abort_transfer () // Abort the ongoing I2C transfer. More...
+                                const int addr8bit = g_I2C_deviceAddress7 << 1;             // 8bit I2C address, 0x90
+                                unsigned int misoLength = 0;
+                                bool repeated = (g_I2C_read_count > 0);
+                                //
+                                int writeStatus = i2cMaster.write (addr8bit, mosiData, byteCount, repeated);
+                                switch (writeStatus)
+                                {
+                                    case 0: cmdLine.serial().printf(" ack "); break;
+                                    case 1: cmdLine.serial().printf(" nack "); break;
+                                    default: cmdLine.serial().printf(" {writeStatus 0x%2.2X} ",
+                                                                     writeStatus);
+                                }
+                                if (repeated)
+                                {
+                                    int readStatus =
+                                        i2cMaster.read (addr8bit, misoData, g_I2C_read_count, false);
+                                    switch (readStatus)
+                                    {
+                                        case 1: cmdLine.serial().printf(" nack "); break;
+                                        case 0: cmdLine.serial().printf(" ack "); break;
+                                        default: cmdLine.serial().printf(" {readStatus 0x%2.2X} ",
+                                                                         readStatus);
+                                    }
+                                }
+                                //
+                                if (misoLength > 0)
+                                {
+                                    // hex dump misoData[0..byteCount-1]
+                                    cmdLine.serial().printf("  MISO<-");
+                                    for (unsigned int byteIndex = 0; byteIndex < g_I2C_read_count;
+                                         byteIndex++)
+                                    {
+                                        cmdLine.serial().printf(" 0x%2.2X", misoData[byteIndex]);
+                                    }
+                                }
+                                cmdLine.serial().printf(" ");
+                            }
+                        }
+                        break;
+                        case 'R': case 'r':
+                        {
+                            // declare in narrower scope: MAX32625MBED I2C i2cMaster(...)
+                            I2C i2cMaster(I2C0_SDA, I2C0_SCL);             // sda scl TARGET_MAX32635MBED: P1_6, P1_7 Arduino 10-pin header
+                            i2cMaster.frequency(g_I2C_SCL_Hz);
+                            // %IR ADDR=? RD=? -- read
+                            // TODO: i2c transfer
+                            //const int addr7bit = 0x48;      // 7 bit I2C address
+                            //const int addr8bit = 0x48 << 1; // 8bit I2C address, 0x90
+                            // /* int  */   i2cMaster.read (int addr8bit, char *data, int length, bool repeated=false) // Read from an I2C slave.
+                            // /* int  */   i2cMaster.read (int ack) // Read a single byte from the I2C bus.
+                            // /* int  */   i2cMaster.write (int addr8bit, const char *data, int length, bool repeated=false) // Write to an I2C slave.
+                            // /* int  */   i2cMaster.write (int data) // Write single byte out on the I2C bus.
+                            // /* void */   i2cMaster.start (void) // Creates a start condition on the I2C bus.
+                            // /* void */   i2cMaster.stop (void) // Creates a stop condition on the I2C bus.
+                            // /* int */    i2cMaster.transfer (int addr8bit, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length, const event_callback_t &callback, int event=I2C_EVENT_TRANSFER_COMPLETE, bool repeated=false) // Start nonblocking I2C transfer. More...
+                            // /* void */   i2cMaster.abort_transfer () // Abort the ongoing I2C transfer. More...
+                        }
+                        break;
+                        case '^':
+                        {
+                            // declare in narrower scope: MAX32625MBED I2C i2cMaster(...)
+                            I2C i2cMaster(I2C0_SDA, I2C0_SCL);             // sda scl TARGET_MAX32635MBED: P1_6, P1_7 Arduino 10-pin header
+                            i2cMaster.frequency(g_I2C_SCL_Hz);
+                            // %I^ cmd=? -- i2c_smbus_read_word_data
+                            // TODO: i2c transfer
+                            //const int addr7bit = 0x48;      // 7 bit I2C address
+                            //const int addr8bit = 0x48 << 1; // 8bit I2C address, 0x90
+                            // /* int  */   i2cMaster.read (int addr8bit, char *data, int length, bool repeated=false) // Read from an I2C slave.
+                            // /* int  */   i2cMaster.read (int ack) // Read a single byte from the I2C bus.
+                            // /* int  */   i2cMaster.write (int addr8bit, const char *data, int length, bool repeated=false) // Write to an I2C slave.
+                            // /* int  */   i2cMaster.write (int data) // Write single byte out on the I2C bus.
+                            // /* void */   i2cMaster.start (void) // Creates a start condition on the I2C bus.
+                            // /* void */   i2cMaster.stop (void) // Creates a stop condition on the I2C bus.
+                            // /* int */    i2cMaster.transfer (int addr8bit, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length, const event_callback_t &callback, int event=I2C_EVENT_TRANSFER_COMPLETE, bool repeated=false) // Start nonblocking I2C transfer. More...
+                            // /* void */   i2cMaster.abort_transfer () // Abort the ongoing I2C transfer. More...
+                        }
+                        break;
+                    }         // switch(cmdLine[2])
+                    break;
+#endif
+                //
+#if HAS_SPI // SUPPORT_SPI
+                case 'S': case 's':
+                {
+                    // %S... -- SPI diagnostics
+                    // %SC sclk=1Mhz -- SPI configure
+                    // %SW -- write (write and read)
+                    // %SR -- read (alias for %SW because SPI always write and read)
+                    //
+                    // Process arguments SCLK=\d+(kHZ|MHZ) CPOL=\d CPHA=\d
+                    bool isUpdatedSPIConfig = false;
+                    // parse cmdLine arg (CPOL=\d)? --> g_SPI_dataMode | SPI_MODE2
+                    // parse cmdLine arg (CPHA=\d)? --> g_SPI_dataMode | SPI_MODE1
+                    if (cmdLine.parse_flag("CPOL", g_SPI_dataMode, SPI_MODE2))
+                    {
+                        isUpdatedSPIConfig = true;
+                    }
+                    if (cmdLine.parse_flag("CPHA", g_SPI_dataMode, SPI_MODE1))
+                    {
+                        isUpdatedSPIConfig = true;
+                    }
+                    if (cmdLine.parse_flag("CS", g_SPI_cs_state, 1))
+                    {
+                        isUpdatedSPIConfig = true;
+                    }
+                    // parse cmdLine arg (SCLK=\d+(kHZ|MHZ)?)? --> g_SPI_SCLK_Hz
+                    if (cmdLine.parse_frequency_Hz("SCLK", g_SPI_SCLK_Hz))
+                    {
+                        isUpdatedSPIConfig = true;
+                        // TODO1: validate g_SPI_SCLK_Hz against system clock frequency F_CPU
+                        if (g_SPI_SCLK_Hz > limit_max_SPI_SCLK_Hz)
+                        {
+                            g_SPI_SCLK_Hz = limit_max_SPI_SCLK_Hz;
+                        }
+                        if (g_SPI_SCLK_Hz < limit_min_SPI_SCLK_Hz)
+                        {
+                            g_SPI_SCLK_Hz = limit_min_SPI_SCLK_Hz;
+                        }
+                    }
+                    // Update SPI configuration
+                    if (isUpdatedSPIConfig)
+                    {
+                        // %SC sclk=1Mhz -- SPI configure
+                        spi_cs = g_SPI_cs_state;
+                        spi.format(8,g_SPI_dataMode);             // int bits_must_be_8, int mode=0_3 CPOL=0,CPHA=0
+#if APPLICATION_MAX5715
+                        g_MAX5715_device.spi_frequency(g_SPI_SCLK_Hz);
+#elif APPLICATION_MAX11131
+                        g_MAX11131_device.spi_frequency(g_SPI_SCLK_Hz);
+#elif APPLICATION_MAX5171
+                        g_MAX5171_device.spi_frequency(g_SPI_SCLK_Hz);
+#elif APPLICATION_MAX11410
+                        g_MAX11410_device.spi_frequency(g_SPI_SCLK_Hz);
+#elif APPLICATION_MAX12345
+                        g_MAX12345_device.spi_frequency(g_SPI_SCLK_Hz);
+#else
+                        spi.frequency(g_SPI_SCLK_Hz);             // int SCLK_Hz=1000000 = 1MHz (initial default)
+#endif
+                        //
+                        double ideal_divisor = ((double)SystemCoreClock) / g_SPI_SCLK_Hz;
+                        int actual_divisor = (int)(ideal_divisor + 0.0);             // frequency divisor truncate
+                        double actual_SCLK_Hz = SystemCoreClock / actual_divisor;
+                        //
+                        // fixed: mbed-os-5.11: [Warning] format '%d' expects argument of type 'int', but argument 6 has type 'uint32_t {aka long unsigned int}' [-Wformat=]
+                        cmdLine.serial().printf(
+                            "\r\n %%SC CPOL=%d CPHA=%d CS=%d SCLK=%ld=%1.3fMHz (%1.1fMHz/%1.2f = actual %1.3fMHz) -- SPI config",
+                            ((g_SPI_dataMode & SPI_MODE2) ? 1 : 0),
+                            ((g_SPI_dataMode & SPI_MODE1) ? 1 : 0),
+                            g_SPI_cs_state,
+                            g_SPI_SCLK_Hz,
+                            (g_SPI_SCLK_Hz / 1000000.),
+                            ((double)(SystemCoreClock / 1000000.)),
+                            ideal_divisor,
+                            (actual_SCLK_Hz / 1000000.)
+                            );
+                    }
+                    // get next character
+                    switch (cmdLine[2])
+                    {
+                        case 'C': case 's':
+                            // %SC sclk=1Mhz -- SPI configure
+                            break;
+                        case 'W': case 'R': case 'w': case 'r':
+                        {
+                            // %SW -- write (write and read)
+                            // %SR -- read (alias for %SW because SPI always write and read)
+                            // parse cmdLine byte list --> int byteCount; int mosiData[MAX_SPI_BYTE_COUNT];
+                            #define MAX_SPI_BYTE_COUNT 32
+                            size_t byteCount = byteCount;
+                            static char mosiData[MAX_SPI_BYTE_COUNT];
+                            static char misoData[MAX_SPI_BYTE_COUNT];
+                            if (cmdLine.parse_byteCount_byteList_hex(byteCount, mosiData,
+                                                                     MAX_SPI_BYTE_COUNT))
+                            {
+                                // hex dump mosiData[0..byteCount-1]
+                                cmdLine.serial().printf("\r\nSPI");
+                                if (byteCount > 7) {
+                                    cmdLine.serial().printf(" byteCount:%d", byteCount);
+                                }
+                                cmdLine.serial().printf(" MOSI->");
+                                for (unsigned int byteIndex = 0; byteIndex < byteCount; byteIndex++)
+                                {
+                                    cmdLine.serial().printf(" 0x%2.2X", mosiData[byteIndex]);
+                                }
+                                spi_cs = 0;
+                                unsigned int numBytesTransferred =
+                                    spi.write(mosiData, byteCount, misoData, byteCount);
+                                spi_cs = 1;
+                                // hex dump misoData[0..byteCount-1]
+                                cmdLine.serial().printf("  MISO<-");
+                                for (unsigned int byteIndex = 0; byteIndex < numBytesTransferred;
+                                     byteIndex++)
+                                {
+                                    cmdLine.serial().printf(" 0x%2.2X", misoData[byteIndex]);
+                                }
+                                cmdLine.serial().printf(" ");
+                            }
+                        }
+                        break;
+                    }             // switch(cmdLine[2])
+                }             // case 'S': // %S... -- SPI diagnostics
+                break;
+#endif
+                //
+                // A-Z,a-z,0-9 reserved for application use
+            }         // switch(cmdLine[1])
+        }
+        break;         // case '%'
+#endif // APPLICATION_ArduinoPinsMonitor
+       //
+       // Application-specific commands here
+       // alphanumeric command codes A-Z,a-z,0-9 reserved for application use
+       //
+#if APPLICATION_ArduinoPinsMonitor
+#endif // APPLICATION_ArduinoPinsMonitor
+
+#if APPLICATION_MAX5715 // main_menu_onEOLcommandParser
+        case '0':
+        {
+            // recommended for hex command codes 00..0F
+            // TODO: cmdLine.serial().printf("\r\n 0 ch=? code=? -- CODEn");
+            // Menu 0 ch=? code=?) CODEn
+            // MAX5715_CODEn(uint8_t channel, uint16_t dacCodeLsbs);
+            // VERIFY: parse strCommandArgs for additional arguments including key=value pairs
+            // TODO: parse command arguments ~ parse_strCommandArgs(strCommandArgs);
+            uint16_t ch = g_MAX5715_device.channelNumber_0_3;
+            if (cmdLine.parse_uint16_dec("ch", ch))
+            {
+            }
+            uint16_t code = g_MAX5715_device.CODE[ch];
+            if (cmdLine.parse_uint16_dec("code", code))
+            {
+            }
+            cmdLine.serial().printf("CODEn ch=%d code=%d", ch, code);
+            g_MAX5715_device.CODEn(ch, code);
+        }
+        break;
+        case '1':
+        {
+            // recommended for hex command codes 10..1F
+            // TODO: cmdLine.serial().printf("\r\n 1 ch=? -- LOADn");
+            // TODO: parse command arguments ~ parse_strCommandArgs(strCommandArgs);
+            uint16_t ch = g_MAX5715_device.channelNumber_0_3;
+            if (cmdLine.parse_uint16_dec("ch", ch))
+            {
+            }
+            cmdLine.serial().printf("LOADn ch=%d", ch);
+            g_MAX5715_device.LOADn(ch);
+        }
+        break;
+        case '2':
+        {
+            // recommended for hex command codes 20..2F
+            // TODO: cmdLine.serial().printf("\r\n 2 ch=? code=? -- CODEnLOADall");
+            // TODO: parse command arguments ~ parse_strCommandArgs(strCommandArgs);
+            uint16_t ch = g_MAX5715_device.channelNumber_0_3;
+            if (cmdLine.parse_uint16_dec("ch", ch))
+            {
+            }
+            uint16_t code = g_MAX5715_device.CODE[ch];
+            if (cmdLine.parse_uint16_dec("code", code))
+            {
+            }
+            cmdLine.serial().printf("CODEnLOADall ch=%d code=%d", ch, code);
+            g_MAX5715_device.CODEnLOADall(ch, code);
+        }
+        break;
+        case '3':
+        {
+            // recommended for hex command codes 30..3F
+            // TODO: cmdLine.serial().printf("\r\n 3 ch=? code=? -- CODEnLOADn");
+            // TODO: parse command arguments ~ parse_strCommandArgs(strCommandArgs);
+            uint16_t ch = g_MAX5715_device.channelNumber_0_3;
+            uint16_t code;
+            if (cmdLine.parse_uint16_dec("ch", ch))
+            {
+            }
+            if (cmdLine.parse_uint16_dec("code", code))
+            {
+            }
+            cmdLine.serial().printf("CODEnLOADn ch=%d code=%d", ch, code);
+            g_MAX5715_device.CODEnLOADn(ch, code);
+        }
+        break;
+        case '4':
+        {
+            // recommended for hex command codes 40..4F
+            switch (cmdLine[1])
+            {
+                case '0':
+                {
+                    // cmdLine.serial().printf("\r\n 40 ch=? -- POWERn_Normal");
+                    cmdLine.serial().printf(
+                        "channel_dcba=%d, POWERn_Normal)",
+                        g_MAX5715_device.channels_bitmask_DCBA);
+                    g_MAX5715_device.POWER(g_MAX5715_device.
+                                           channels_bitmask_DCBA,
+                                           MAX5715::POWERn_Normal);
+                }
+                break;
+                case '1':
+                {
+                    // cmdLine.serial().printf("\r\n 41 ch=? -- POWERn_PD1k");
+                    cmdLine.serial().printf(
+                        "channel_dcba=%d, POWERn_PD1k)",
+                        g_MAX5715_device.channels_bitmask_DCBA);
+                    g_MAX5715_device.POWER(g_MAX5715_device.
+                                           channels_bitmask_DCBA,
+                                           MAX5715::POWERn_PD1k);
+                }
+                break;
+                case '2':
+                {
+                    // cmdLine.serial().printf("\r\n 42 ch=? -- POWERn_PD100k");
+                    cmdLine.serial().printf(
+                        "channel_dcba=%d, POWERn_PD100k)",
+                        g_MAX5715_device.channels_bitmask_DCBA);
+                    g_MAX5715_device.POWER(g_MAX5715_device.
+                                           channels_bitmask_DCBA,
+                                           MAX5715::POWERn_PD100k);
+                }
+                break;
+                case '3':
+                {
+                    // cmdLine.serial().printf("\r\n 43 ch=? -- POWERn_PDHiZ");
+                    cmdLine.serial().printf(
+                        "channel_dcba=%d, POWERn_PDHiZ)",
+                        g_MAX5715_device.channels_bitmask_DCBA);
+                    g_MAX5715_device.POWER(g_MAX5715_device.
+                                           channels_bitmask_DCBA,
+                                           MAX5715::POWERn_PDHiZ);
+                }
+                break;
+            }
+            break;
+        }
+        break;
+        case '5':
+        {
+            // recommended for hex command codes 50..5F
+            switch (cmdLine[1])
+            {
+                case '0':
+                {
+                    // cmdLine.serial().printf("\r\n 50 -- SW_CLEAR");
+                    cmdLine.serial().printf("SW_CLEAR");
+                    g_MAX5715_device.SW_CLEAR();
+                }
+                break;
+                case '1':
+                {
+                    // cmdLine.serial().printf("\r\n 51 -- SW_RESET");
+                    cmdLine.serial().printf("SW_RESET");
+                    g_MAX5715_device.SW_RESET();
+                }
+                break;
+            }
+        }
+        break;
+        case '6':
+        {
+            // recommended for hex command codes 60..6F
+            switch (cmdLine[1])
+            {
+                case '0':
+                {
+                    // cmdLine.serial().printf("\r\n 60 ch=? -- CONFIGn_LATCHED");
+                    cmdLine.serial().printf(
+                        "MAX5715_CONFIGn_LATCHED(channel_dcba=%d)",
+                        g_MAX5715_device.
+                        channels_bitmask_DCBA);
+                    g_MAX5715_device.CONFIGn_LATCHED(g_MAX5715_device.
+                                                     channels_bitmask_DCBA);
+                }
+                break;
+                case '1':
+                {
+                    // cmdLine.serial().printf("\r\n 61 ch=? -- CONFIGn_TRANSPARENT");
+                    cmdLine.serial().printf(
+                        "MAX5715_CONFIGn_TRANSPARENT(channel_dcba=%d)",
+                        g_MAX5715_device.
+                        channels_bitmask_DCBA);
+                    g_MAX5715_device.CONFIGn_TRANSPARENT(
+                        g_MAX5715_device.channels_bitmask_DCBA);
+                }
+                break;
+                case '8':
+                {
+                    // cmdLine.serial().printf("\r\n 68 -- CONFIGall_LATCHED");
+                    cmdLine.serial().printf(
+                        "MAX5715_CONFIGall_LATCHED()");
+                    g_MAX5715_device.CONFIGall_LATCHED();
+                }
+                break;
+                case '9':
+                {
+                    // cmdLine.serial().printf("\r\n 69 -- CONFIGall_TRANSPARENT");
+                    cmdLine.serial().printf(
+                        "MAX5715_CONFIGall_TRANSPARENT()");
+                    g_MAX5715_device.CONFIGall_TRANSPARENT();
+                }
+                break;
+            }
+        }
+        break;
+        case '7':
+        {
+            // recommended for hex command codes 70..7F
+            switch (cmdLine[1])
+            {
+                case '0':
+                {
+                    // cmdLine.serial().printf("\r\n 70 -- REF_EXT");
+                    cmdLine.serial().printf(
+                        "MAX5715_REF(REF_EXT)");
+                    g_MAX5715_device.REF(MAX5715::REF_EXT);
+                }
+                break;
+                case '1':
+                {
+                    // cmdLine.serial().printf("\r\n 71 -- REF_2V500");
+                    cmdLine.serial().printf(
+                        "MAX5715_REF(REF_2V500)");
+                    g_MAX5715_device.REF(MAX5715::REF_2V500);
+                }
+                break;
+                case '2':
+                {
+                    // cmdLine.serial().printf("\r\n 72 -- REF_2V048");
+                    cmdLine.serial().printf(
+                        "MAX5715_REF(REF_2V048)");
+                    g_MAX5715_device.REF(MAX5715::REF_2V048);
+                }
+                break;
+                case '3':
+                {
+                    // cmdLine.serial().printf("\r\n 73 -- REF_4V096");
+                    cmdLine.serial().printf(
+                        "MAX5715_REF(REF_4V096)");
+                    g_MAX5715_device.REF(MAX5715::REF_4V096);
+                }
+                break;
+                case '4':
+                {
+                    // cmdLine.serial().printf("\r\n 74 -- REF_AlwaysOn_EXT");
+                    cmdLine.serial().printf(
+                        "MAX5715_REF(REF_AlwaysOn_EXT)");
+                    g_MAX5715_device.REF(MAX5715::REF_AlwaysOn_EXT);
+                }
+                break;
+                case '5':
+                {
+                    // cmdLine.serial().printf("\r\n 75 -- REF_AlwaysOn_2V500");
+                    cmdLine.serial().printf(
+                        "MAX5715_REF(REF_AlwaysOn_2V500)");
+                    g_MAX5715_device.REF(MAX5715::REF_AlwaysOn_2V500);
+                }
+                break;
+                case '6':
+                {
+                    // cmdLine.serial().printf("\r\n 76 -- REF_AlwaysOn_2V048");
+                    cmdLine.serial().printf(
+                        "MAX5715_REF(REF_AlwaysOn_2V048)");
+                    g_MAX5715_device.REF(MAX5715::REF_AlwaysOn_2V048);
+                }
+                break;
+                case '7':
+                {
+                    // cmdLine.serial().printf("\r\n 77 -- REF_AlwaysOn_4V096");
+                    cmdLine.serial().printf(
+                        "MAX5715_REF(REF_AlwaysOn_4V096)");
+                    g_MAX5715_device.REF(MAX5715::REF_AlwaysOn_4V096);
+                }
+                break;
+            }
+        }
+        break;
+        case '8':
+        {
+            // recommended for hex command codes 80..8F
+            switch (cmdLine[1])
+            {
+                case '0':
+                {
+                    // TODO: cmdLine.serial().printf("\r\n 80 code=? -- CODEall");
+                    // TODO: parse command arguments ~ parse_strCommandArgs(strCommandArgs);
+                    g_MAX5715_device.channels_bitmask_DCBA = 0xFF;             // store g_MAX5715_device.CODE[allChannels]
+                    uint16_t code = g_MAX5715_device.CODE[0];
+                    if (cmdLine.parse_uint16_dec("code", code))
+                    {
+                    }
+                    cmdLine.serial().printf("CODEall code=%d", code);
+                    g_MAX5715_device.CODEall(code);
+                }
+                break;
+                case '1':
+                {
+                    // TODO: cmdLine.serial().printf("\r\n 81 -- LOADall");
+                    cmdLine.serial().printf("LOADall");
+                    g_MAX5715_device.LOADall();
+                }
+                break;
+                case '2':
+                {
+                    // TODO: cmdLine.serial().printf("\r\n 82 code=? -- CODEallLOADall");
+                    uint16_t code = g_MAX5715_device.CODE[0];
+                    if (cmdLine.parse_uint16_dec("code", code))
+                    {
+                    }
+                    cmdLine.serial().printf("CODEallLOADall code=%d", code);
+                    g_MAX5715_device.CODEallLOADall(code);
+                }
+                break;
+            }
+        }
+        break;
+        case '9':
+        {
+            // recommended for hex command codes 90..9F
+        }
+        break;
+        case 'a': case 'A':
+        {
+            // recommended for hex command codes A0..AF
+            switch (cmdLine[1])
+            {
+                case 't': case 'T':
+#if IGNORE_AT_COMMANDS
+# if HAS_DAPLINK_SERIAL
+                    cmdLine_DAPLINKserial.serial().printf("\r\n ignore AT command \"%s\"\r\n", cmdLine.str());
+# endif // HAS_DAPLINK_SERIAL
+                    // AT command: skip the prompt to avoid confusing modem detector
+                    return;
+#endif // IGNORE_AT_COMMANDS
+            }
+        }
+        break;
+        case 'b': case 'B':
+        {
+            // recommended for hex command codes B0..BF
+        }
+        break;
+        case 'c': case 'C':
+        {
+            // recommended for hex command codes C0..CF
+            // // MAX5717 menu function to drive MAX5717_CLRb_Pin CLR#
+            // cmdLine.serial().printf("\r\n C -- CLR# pulse CH high CL low");
+            switch (cmdLine[1])
+            {
+                default:
+                    // g_MAX5715_device.CLRboutputPulseLow();
+                    g_MAX5715_device.CLRboutputValue(1);
+                    g_MAX5715_device.CLRboutputValue(0);
+                    g_MAX5715_device.CLRboutputValue(1);
+                    break;
+                case 'H': case 'h': case '1':
+                    g_MAX5715_device.CLRboutputValue(1);         // GPIOoutputCLRb(int isLogicHigh);
+                    break;
+                case 'L': case 'l': case '0':
+                    g_MAX5715_device.CLRboutputValue(0);         // GPIOoutputCLRb(int isLogicHigh);
+                    break;
+            }
+        }
+        break;
+        case 'd': case 'D':
+        {
+            // recommended for hex command codes D0..DF
+        }
+        break;
+        case 'e': case 'E':
+        {
+            // recommended for hex command codes E0..EF
+        }
+        break;
+        case 'f': case 'F':
+        {
+            // recommended for hex command codes F0..FF
+        }
+        break;
+        case 'l': case 'L':
+        {
+            // // MAX5717 menu function to drive MAX5717_LDACb_Pin LDAC#
+            // cmdLine.serial().printf("\r\n L -- LDAC# pulse LH high LL low");
+            switch (cmdLine[1])
+            {
+                default:
+                    // g_MAX5715_device.LDACboutputPulseLow();
+                    g_MAX5715_device.LDACboutputValue(1);
+                    g_MAX5715_device.LDACboutputValue(0);
+                    g_MAX5715_device.LDACboutputValue(1);
+                    break;
+                case 'H': case 'h': case '1':
+                    g_MAX5715_device.LDACboutputValue(1);         // GPIOoutputLDACb(int isLogicHigh);
+                    break;
+                case 'L': case 'l': case '0':
+                    g_MAX5715_device.LDACboutputValue(0);         // GPIOoutputLDACb(int isLogicHigh);
+                    break;
+            }
+        }
+        break;
+        case 'x': case 'X':
+        {
+        }
+        break;
+        case 'y': case 'Y':
+        {
+        }
+        break;
+        case 'z': case 'Z':
+        {
+        }
+        break;
+        case '~':     // TODO: IGNORE_AT_COMMANDS -- ignore ~~~ modem command
+        {
+            // TODO: '~' is not recommended for menu commands, interferes with ssh
+            switch (cmdLine[1])
+            {
+                default:
+                {
+#if IGNORE_AT_COMMANDS
+# if HAS_DAPLINK_SERIAL
+                    cmdLine_DAPLINKserial.serial().printf("\r\n ignore AT command \"%s\"\r\n",
+                                                          cmdLine.str());
+# endif // HAS_DAPLINK_SERIAL
+#endif // IGNORE_AT_COMMANDS
+                }
+            }
+        }
+        break;
+        case '+':     // TODO: IGNORE_AT_COMMANDS -- ignore +++ modem command
+        {
+#if IGNORE_AT_COMMANDS
+# if HAS_DAPLINK_SERIAL
+            cmdLine_DAPLINKserial.serial().printf("\r\n ignore AT command \"%s\"\r\n", cmdLine.str());
+# endif // HAS_DAPLINK_SERIAL
+#endif // IGNORE_AT_COMMANDS
+        }
+        break;
+        case '@':
+        {
+            // //
+            // // Menu @ -- print device configuration
+            // TODO: cmdLine.serial().printf("\r\n @ -- print MAX5715 configuration");
+            // //
+            // print shadow register configuration
+            //
+            // shadow of write-only register CODE dddd_dddd_dddd_0000
+            //~ int16_t CMD_1000_CODE;
+            int index = 0;
+            for (index = 0; index < 4; index++)
+            {
+                cmdLine.serial().printf("CODE %c=0x%4.4x MAX5715_VoltageOfCode(%d)=%5.3fV\r\n",
+                                        (char)('A' + index),
+                                        (g_MAX5715_device.Shadow_0010_nnnn_CODE[index] & 0xFFFF),
+                                        g_MAX5715_device.CODE[index],
+                                        g_MAX5715_device.VoltageOfCode(g_MAX5715_device.CODE[index])
+                                        );
+            }
+            //
+            cmdLine.serial().printf("\r\n");
+            //
+            //
+            // Menu @) print MAX5715 configuration AND g_MAX5715_device globals
+            //
+#if 1 // SUPPORT_CHANNELS
+            cmdLine.serial().printf("channelNumber_0_3=%d channels_bitmask_DCBA=%d\r\n",
+                                    (g_MAX5715_device.channelNumber_0_3 & 0xFFFF),
+                                    (g_MAX5715_device.channels_bitmask_DCBA & 0xFFFF));
+#endif // SUPPORT_CHANNELS
+            //
+            cmdLine.serial().printf("VRef=%5.3fV\r\n", g_MAX5715_device.VRef);
+            // dtostrf width and precision: 3.3V / 1024 LSB = 0.00322265625 volts per LSB
+        }
+        break;
+#endif // APPLICATION_MAX5715
+
+#if APPLICATION_MAX11131 // main_menu_onEOLcommandParser
+        case '0':
+        {
+            // recommended for hex command codes 00..0F
+            // VERIFY: console menu command 0 int16_t MAX11131_ScanRead(void);
+            // TODO: cmdLine.serial().printf("\r\n 0 n=?                                  -- MAX11131_ScanRead");
+            if (cmdLine.parse_uint16_dec("n", g_MAX11131_device.NumWords))
+            {
+            }
+            cmdLine.serial().printf("ScanRead NumWords=%d", g_MAX11131_device.NumWords);
+            if (g_MAX11131_device.isExternalClock)
+            {
+                cmdLine.serial().printf(" External Clock");
+                //
+                // Read raw ADC codes from device into AINcode[] and RAW_misoData16[]
+                // @pre one of the MAX11311_Scan functions was called, setting g_MAX11131_device.NumWords
+                g_MAX11131_device.ReadAINcode();
+                // @post RAW_misoData16[index] contains the raw SPI Master-In,Slave-Out data
+                // @post AINcode[NUM_CHANNELS] contains the latest readings in LSBs
+                //
+                AINcode_print_value_externalClock(cmdLine, g_MAX11131_device.NumWords);
+            }
+            else
+            {
+                cmdLine.serial().printf(" Internal Clock");
+                //
+                // Read raw ADC codes from device into AINcode[] and RAW_misoData16[]
+                // @pre one of the MAX11311_Scan functions was called, setting g_MAX11131_device.NumWords
+                g_MAX11131_device.ReadAINcode();
+                // @post RAW_misoData16[index] contains the raw SPI Master-In,Slave-Out data
+                // @post AINcode[NUM_CHANNELS] contains the latest readings in LSBs
+                //
+                AINcode_print_value_chanID(cmdLine, g_MAX11131_device.NumWords);
+            }
+        }
+        break;
+        case '1':
+        {
+            // recommended for hex command codes 10..1F
+            // VERIFY: console menu command 1 MAX11131_ScanManual(int channelNumber_0_15, int PowerManagement_0_2, int chan_id_0_1);
+            // TODO: cmdLine.serial().printf("\r\n 1 ch=? pm=? id=?                       -- MAX11131_ScanManual");
+            if (cmdLine.parse_byte_dec("ch", g_MAX11131_device.channelNumber_0_15))
+            {
+            }
+            if (cmdLine.parse_byte_dec("pm", g_MAX11131_device.PowerManagement_0_2))
+            {
+            }
+            if (cmdLine.parse_byte_dec("id", g_MAX11131_device.chan_id_0_1))
+            {
+            }
+            cmdLine.serial().printf("ScanManual ch=%d pm=%d id=%d\r\n",
+                                    g_MAX11131_device.channelNumber_0_15,
+                                    g_MAX11131_device.PowerManagement_0_2,
+                                    g_MAX11131_device.chan_id_0_1);
+            // VERIFY: replace argument with driver global; g_MAX11131_device.PowerManagement_0_2 replaces PowerManagement_0_2
+            // VERIFY: replace argument with driver global; g_MAX11131_device.chan_id_0_1 replaces chan_id_0_1
+            // VERIFY: replace argument with driver global; g_MAX11131_device.channelNumber_0_15 replaces channelNumber_0_15
+            g_MAX11131_device.NumWords = g_MAX11131_device.ScanManual();
+            //
+            // Read raw ADC codes from device into AINcode[] and RAW_misoData16[]
+            // @pre one of the MAX11311_Scan functions was called, setting g_MAX11131_device.NumWords
+            g_MAX11131_device.ReadAINcode();
+            // @post RAW_misoData16[index] contains the raw SPI Master-In,Slave-Out data
+            // @post AINcode[NUM_CHANNELS] contains the latest readings in LSBs
+            //
+            AINcode_print_value_externalClock(cmdLine, g_MAX11131_device.NumWords);
+        }
+        break;
+        case '2':
+        {
+            // recommended for hex command codes 20..2F
+            // VERIFY: console menu command 2 int MAX11131_ScanRepeat(uint8_t channelNumber_0_15, uint8_t average_0_4_8_16_32, uint8_t nscan_4_8_12_16, uint8_t PowerManagement_0_2, uint8_t swcnv_0_1);
+            // TODO: cmdLine.serial().printf("\r\n 2 ch=? av=? n=? pm=? swcnv=?           -- MAX11131_ScanRepeat");
+            // VERIFY: update value of g_MAX11131_device.channelNumber_0_15 from strCommandArgs
+            // VERIFY: update value of g_MAX11131_device.average_0_4_8_16_32 option from strCommandArgs
+            // VERIFY: update value of g_MAX11131_device.nscan_4_8_12_16 option from strCommandArgs
+            // VERIFY: update value of g_MAX11131_device.swcnv_0_1 option from strCommandArgs
+            // VERIFY: update value of g_MAX11131_device.PowerManagement_0_2 option from strCommandArgs
+            // VERIFY: parse strCommandArgs for additional arguments including key=value pairs
+            if (cmdLine.parse_byte_dec("ch", g_MAX11131_device.channelNumber_0_15))
+            {
+            }
+            if (cmdLine.parse_byte_dec("av", g_MAX11131_device.average_0_4_8_16_32))
+            {
+            }
+            if (cmdLine.parse_byte_dec("n", g_MAX11131_device.nscan_4_8_12_16))
+            {
+            }
+            if (cmdLine.parse_byte_dec("swcnv", g_MAX11131_device.swcnv_0_1))
+            {
+            }
+            if (cmdLine.parse_byte_dec("pm", g_MAX11131_device.PowerManagement_0_2))
+            {
+            }
+            cmdLine.serial().printf(
+                "ScanRepeat ch=%d average_0_4_8_16_32:%d nscan_4_8_12_16:%d swcnv=%d pm=%d\r\n",
+                g_MAX11131_device.channelNumber_0_15,
+                g_MAX11131_device.average_0_4_8_16_32,
+                g_MAX11131_device.nscan_4_8_12_16,
+                g_MAX11131_device.swcnv_0_1,
+                g_MAX11131_device.PowerManagement_0_2);
+            // VERIFY: replace argument with driver global; g_MAX11131_device.PowerManagement_0_2 replaces PowerManagement_0_2
+            // VERIFY: replace argument with driver global; g_MAX11131_device.swcnv_0_1 replaces swcnv_0_1
+            // VERIFY: replace argument with driver global; g_MAX11131_device.nscan_4_8_12_16 replaces nscan_4_8_12_16
+            // VERIFY: replace argument with driver global; g_MAX11131_device.average_0_4_8_16_32 replaces average_0_4_8_16_32
+            // VERIFY: replace argument with driver global; g_MAX11131_device.channelNumber_0_15 replaces channelNumber_0_15
+            g_MAX11131_device.NumWords = g_MAX11131_device.ScanRepeat();
+            //
+            // Read raw ADC codes from device into AINcode[] and RAW_misoData16[]
+            // @pre one of the MAX11311_Scan functions was called, setting g_MAX11131_device.NumWords
+            g_MAX11131_device.ReadAINcode();
+            // @post RAW_misoData16[index] contains the raw SPI Master-In,Slave-Out data
+            // @post AINcode[NUM_CHANNELS] contains the latest readings in LSBs
+            //
+            AINcode_print_value_chanID_mean(cmdLine, g_MAX11131_device.NumWords);
+        }
+        break;
+        case '3':
+        {
+            // recommended for hex command codes 30..3F
+            // VERIFY: console menu command 3 MAX11131_ScanStandardInternalClock(int channelNumber_0_15, int average_0_4_8_16_32, int PowerManagement_0_2, int swcnv_0_1);
+            // TODO: cmdLine.serial().printf("\r\n 3 ch=? av=? pm=? swcnv=?               -- MAX11131_ScanStandardIntClock");
+            // VERIFY: update value of g_MAX11131_device.channelNumber_0_15 from strCommandArgs
+            // VERIFY: update value of g_MAX11131_device.average_0_4_8_16_32 option from strCommandArgs
+            // VERIFY: update value of g_MAX11131_device.swcnv_0_1 option from strCommandArgs
+            // VERIFY: update value of g_MAX11131_device.PowerManagement_0_2 option from strCommandArgs
+            if (cmdLine.parse_byte_dec("ch", g_MAX11131_device.channelNumber_0_15))
+            {
+            }
+            if (cmdLine.parse_byte_dec("av", g_MAX11131_device.average_0_4_8_16_32))
+            {
+            }
+            if (cmdLine.parse_byte_dec("pm", g_MAX11131_device.PowerManagement_0_2))
+            {
+            }
+            if (cmdLine.parse_byte_dec("swcnv", g_MAX11131_device.swcnv_0_1))
+            {
+            }
+            cmdLine.serial().printf("ScanStandardInternalClock ch=%d average_0_4_8_16_32:%d swcnv=%d pm=%d\r\n",
+                                    g_MAX11131_device.channelNumber_0_15,
+                                    g_MAX11131_device.average_0_4_8_16_32,
+                                    g_MAX11131_device.swcnv_0_1,
+                                    g_MAX11131_device.PowerManagement_0_2
+                                    );
+            // VERIFY: replace argument with driver global; g_MAX11131_device.PowerManagement_0_2 replaces PowerManagement_0_2
+            // VERIFY: replace argument with driver global; g_MAX11131_device.swcnv_0_1 replaces swcnv_0_1
+            // VERIFY: replace argument with driver global; g_MAX11131_device.average_0_4_8_16_32 replaces average_0_4_8_16_32
+            // VERIFY: replace argument with driver global; g_MAX11131_device.channelNumber_0_15 replaces channelNumber_0_15
+            g_MAX11131_device.NumWords = g_MAX11131_device.ScanStandardInternalClock();
+            //
+            // Read raw ADC codes from device into AINcode[] and RAW_misoData16[]
+            // @pre one of the MAX11311_Scan functions was called, setting g_MAX11131_device.NumWords
+            g_MAX11131_device.ReadAINcode();
+            // @post RAW_misoData16[index] contains the raw SPI Master-In,Slave-Out data
+            // @post AINcode[NUM_CHANNELS] contains the latest readings in LSBs
+            //
+            AINcode_print_value_chanID(cmdLine, g_MAX11131_device.NumWords);
+        }
+        break;
+        case '4':
+        {
+            // recommended for hex command codes 40..4F
+            // VERIFY: console menu command 4 MAX11131_ScanStandardExternalClock(int channelNumber_0_15, int PowerManagement_0_2, int chan_id_0_1);
+            // TODO: cmdLine.serial().printf("\r\n 4 ch=? pm=? id=?                       -- MAX11131_ScanStandardExtClock");
+            // VERIFY: update value of g_MAX11131_device.channelNumber_0_15 from strCommandArgs
+            // VERIFY: update value of g_MAX11131_device.PowerManagement_0_2 option from strCommandArgs
+            // VERIFY: update value of g_MAX11131_device.chan_id_0_1 option from strCommandArgs
+            if (cmdLine.parse_byte_dec("ch", g_MAX11131_device.channelNumber_0_15))
+            {
+            }
+            if (cmdLine.parse_byte_dec("pm", g_MAX11131_device.PowerManagement_0_2))
+            {
+            }
+            if (cmdLine.parse_byte_dec("id", g_MAX11131_device.chan_id_0_1))
+            {
+            }
+            cmdLine.serial().printf("ScanStandardExternalClock ch=%d pm=%d id=%d\r\n",
+                                    g_MAX11131_device.channelNumber_0_15,
+                                    g_MAX11131_device.PowerManagement_0_2,
+                                    g_MAX11131_device.chan_id_0_1
+                                    );
+            // VERIFY: replace argument with driver global; g_MAX11131_device.PowerManagement_0_2 replaces PowerManagement_0_2
+            // VERIFY: replace argument with driver global; g_MAX11131_device.chan_id_0_1 replaces chan_id_0_1
+            // VERIFY: replace argument with driver global; g_MAX11131_device.channelNumber_0_15 replaces channelNumber_0_15
+            g_MAX11131_device.NumWords = g_MAX11131_device.ScanStandardExternalClock();
+            //
+            // Read raw ADC codes from device into AINcode[] and RAW_misoData16[]
+            // @pre one of the MAX11311_Scan functions was called, setting g_MAX11131_device.NumWords
+            g_MAX11131_device.ReadAINcode();
+            // @post RAW_misoData16[index] contains the raw SPI Master-In,Slave-Out data
+            // @post AINcode[NUM_CHANNELS] contains the latest readings in LSBs
+            //
+            AINcode_print_value_externalClock(cmdLine, g_MAX11131_device.NumWords);
+        }
+        break;
+        case '5':
+        {
+            // recommended for hex command codes 50..5F
+            // VERIFY: console menu command 5 MAX11131_ScanUpperInternalClock(int channelNumber_0_15, int average_0_4_8_16_32, int PowerManagement_0_2, int swcnv_0_1);
+            // TODO: cmdLine.serial().printf("\r\n 5 ch=? av=? pm=? swcnv=?               -- MAX11131_ScanUpperIntClock");
+            // VERIFY: update value of g_MAX11131_device.channelNumber_0_15 from strCommandArgs
+            // VERIFY: update value of g_MAX11131_device.average_0_4_8_16_32 option from strCommandArgs
+            // VERIFY: update value of g_MAX11131_device.swcnv_0_1 option from strCommandArgs
+            // VERIFY: update value of g_MAX11131_device.PowerManagement_0_2 option from strCommandArgs
+            if (cmdLine.parse_byte_dec("ch", g_MAX11131_device.channelNumber_0_15))
+            {
+            }
+            if (cmdLine.parse_byte_dec("av", g_MAX11131_device.average_0_4_8_16_32))
+            {
+            }
+            if (cmdLine.parse_byte_dec("pm", g_MAX11131_device.PowerManagement_0_2))
+            {
+            }
+            if (cmdLine.parse_byte_dec("swcnv", g_MAX11131_device.swcnv_0_1))
+            {
+            }
+            cmdLine.serial().printf("ScanUpperInternalClock ch=%d average_0_4_8_16_32:%d swcnv=%d pm=%d\r\n",
+                                    g_MAX11131_device.channelNumber_0_15,
+                                    g_MAX11131_device.average_0_4_8_16_32,
+                                    g_MAX11131_device.swcnv_0_1,
+                                    g_MAX11131_device.PowerManagement_0_2
+                                    );
+            // VERIFY: replace argument with driver global; g_MAX11131_device.PowerManagement_0_2 replaces PowerManagement_0_2
+            // VERIFY: replace argument with driver global; g_MAX11131_device.swcnv_0_1 replaces swcnv_0_1
+            // VERIFY: replace argument with driver global; g_MAX11131_device.average_0_4_8_16_32 replaces average_0_4_8_16_32
+            // VERIFY: replace argument with driver global; g_MAX11131_device.channelNumber_0_15 replaces channelNumber_0_15
+            g_MAX11131_device.NumWords = g_MAX11131_device.ScanUpperInternalClock();
+            //
+            // Read raw ADC codes from device into AINcode[] and RAW_misoData16[]
+            // @pre one of the MAX11311_Scan functions was called, setting g_MAX11131_device.NumWords
+            g_MAX11131_device.ReadAINcode();
+            // @post RAW_misoData16[index] contains the raw SPI Master-In,Slave-Out data
+            // @post AINcode[NUM_CHANNELS] contains the latest readings in LSBs
+            //
+            AINcode_print_value_chanID(cmdLine, g_MAX11131_device.NumWords);
+        }
+        break;
+        case '6':
+        {
+            // recommended for hex command codes 60..6F
+            // VERIFY: console menu command 6 MAX11131_ScanUpperExternalClock(int channelNumber_0_15, int PowerManagement_0_2, int chan_id_0_1);
+            // TODO: cmdLine.serial().printf("\r\n 6 ch=? pm=? id=?                       -- MAX11131_ScanUpperExtClock");
+            // VERIFY: update value of g_MAX11131_device.channelNumber_0_15 from strCommandArgs
+            // VERIFY: update value of g_MAX11131_device.PowerManagement_0_2 option from strCommandArgs
+            // VERIFY: update value of g_MAX11131_device.chan_id_0_1 option from strCommandArgs
+            if (cmdLine.parse_byte_dec("ch", g_MAX11131_device.channelNumber_0_15))
+            {
+            }
+            if (cmdLine.parse_byte_dec("pm", g_MAX11131_device.PowerManagement_0_2))
+            {
+            }
+            if (cmdLine.parse_byte_dec("id", g_MAX11131_device.chan_id_0_1))
+            {
+            }
+            cmdLine.serial().printf("ScanUpperExternalClock ch=%d pm=%d id=%d\r\n",
+                                    g_MAX11131_device.channelNumber_0_15,
+                                    g_MAX11131_device.PowerManagement_0_2,
+                                    g_MAX11131_device.chan_id_0_1
+                                    );
+            // VERIFY: replace argument with driver global; g_MAX11131_device.PowerManagement_0_2 replaces PowerManagement_0_2
+            // VERIFY: replace argument with driver global; g_MAX11131_device.chan_id_0_1 replaces chan_id_0_1
+            // VERIFY: replace argument with driver global; g_MAX11131_device.channelNumber_0_15 replaces channelNumber_0_15
+            g_MAX11131_device.NumWords = g_MAX11131_device.ScanUpperExternalClock();
+            //
+            // Read raw ADC codes from device into AINcode[] and RAW_misoData16[]
+            // @pre one of the MAX11311_Scan functions was called, setting g_MAX11131_device.NumWords
+            g_MAX11131_device.ReadAINcode();
+            // @post RAW_misoData16[index] contains the raw SPI Master-In,Slave-Out data
+            // @post AINcode[NUM_CHANNELS] contains the latest readings in LSBs
+            //
+            AINcode_print_value_externalClock(cmdLine, g_MAX11131_device.NumWords);
+        }
+        break;
+        case '7':
+        {
+            // recommended for hex command codes 70..7F
+            // VERIFY: console menu command 7 MAX11131_ScanCustomInternalClock(int16_t enabledChannelsMask, int average_0_4_8_16_32, int PowerManagement_0_2, int swcnv_0_1);
+            // TODO: cmdLine.serial().printf("\r\n 7 enableMask=0xffff av=? pm=? swcnv=?  -- MAX11131_ScanCustomIntClock");
+            // VERIFY: update value of g_MAX11131_device.average_0_4_8_16_32 option from strCommandArgs
+            // VERIFY: update value of g_MAX11131_device.swcnv_0_1 option from strCommandArgs
+            // VERIFY: update value of g_MAX11131_device.PowerManagement_0_2 option from strCommandArgs
+            if (cmdLine.parse_int16_hex("enableMask", g_MAX11131_device.enabledChannelsMask))
+            {
+                // TODO1: get g_MAX11131_device.enabledChannelsMask from strCommandArgs
+            }
+            if (cmdLine.parse_byte_dec("av", g_MAX11131_device.average_0_4_8_16_32))
+            {
+            }
+            if (cmdLine.parse_byte_dec("pm", g_MAX11131_device.PowerManagement_0_2))
+            {
+            }
+            if (cmdLine.parse_byte_dec("swcnv", g_MAX11131_device.swcnv_0_1))
+            {
+            }
+            cmdLine.serial().printf(
+                "ScanCustomInternalClock enabledChannelsMask:0x%4.4x average_0_4_8_16_32:%d pm=%d swcnv=%d\r\n",
+                (g_MAX11131_device.enabledChannelsMask & 0xFFFF),
+                g_MAX11131_device.average_0_4_8_16_32,
+                g_MAX11131_device.PowerManagement_0_2,
+                g_MAX11131_device.swcnv_0_1
+                );
+            // VERIFY: replace argument with driver global; g_MAX11131_device.PowerManagement_0_2 replaces PowerManagement_0_2
+            // VERIFY: replace argument with driver global; g_MAX11131_device.swcnv_0_1 replaces swcnv_0_1
+            // VERIFY: replace argument with driver global; g_MAX11131_device.average_0_4_8_16_32 replaces average_0_4_8_16_32
+            // VERIFY: replace argument with driver global; g_MAX11131_device.enabledChannelsMask replaces enabledChannelsMask
+            g_MAX11131_device.NumWords = g_MAX11131_device.ScanCustomInternalClock();
+            //
+            // Read raw ADC codes from device into AINcode[] and RAW_misoData16[]
+            // @pre one of the MAX11311_Scan functions was called, setting g_MAX11131_device.NumWords
+            g_MAX11131_device.ReadAINcode();
+            // @post RAW_misoData16[index] contains the raw SPI Master-In,Slave-Out data
+            // @post AINcode[NUM_CHANNELS] contains the latest readings in LSBs
+            //
+            AINcode_print_value_chanID(cmdLine, g_MAX11131_device.NumWords);
+        }
+        break;
+        case '8':
+        {
+            // recommended for hex command codes 80..8F
+            // VERIFY: console menu command 8 MAX11131_ScanCustomExternalClock(int16_t enabledChannelsMask, int PowerManagement_0_2, int chan_id_0_1);
+            // TODO: cmdLine.serial().printf("\r\n 8 enableMask=0xffff pm=0 id=1               -- MAX11131_ScanCustomExtClock");
+            if (cmdLine.parse_int16_hex("enableMask", g_MAX11131_device.enabledChannelsMask))
+            {
+                // TODO1: get g_MAX11131_device.enabledChannelsMask from strCommandArgs
+            }
+            if (cmdLine.parse_byte_dec("pm", g_MAX11131_device.PowerManagement_0_2))
+            {
+            }
+            if (cmdLine.parse_byte_dec("id", g_MAX11131_device.chan_id_0_1))
+            {
+            }
+            cmdLine.serial().printf("ScanCustomExternalClock enabledChannelsMask:0x%4.4x pm=%d id=%d\r\n",
+                                    (g_MAX11131_device.enabledChannelsMask & 0xFFFF),
+                                    g_MAX11131_device.PowerManagement_0_2,
+                                    g_MAX11131_device.chan_id_0_1
+                                    );
+            // VERIFY: replace argument with driver global; g_MAX11131_device.PowerManagement_0_2 replaces PowerManagement_0_2
+            // VERIFY: replace argument with driver global; g_MAX11131_device.chan_id_0_1 replaces chan_id_0_1
+            // VERIFY: replace argument with driver global; g_MAX11131_device.enabledChannelsMask replaces enabledChannelsMask
+            g_MAX11131_device.NumWords = g_MAX11131_device.ScanCustomExternalClock();
+            //
+            // Read raw ADC codes from device into AINcode[] and RAW_misoData16[]
+            // @pre one of the MAX11311_Scan functions was called, setting g_MAX11131_device.NumWords
+            g_MAX11131_device.ReadAINcode();
+            // @post RAW_misoData16[index] contains the raw SPI Master-In,Slave-Out data
+            // @post AINcode[NUM_CHANNELS] contains the latest readings in LSBs
+            //
+            AINcode_print_value_externalClock(cmdLine, g_MAX11131_device.NumWords);
+        }
+        break;
+        case '9':
+        {
+            // recommended for hex command codes 90..9F
+            // VERIFY: console menu command 9 MAX11131_ScanSampleSetExternalClock(uint8_t enabledChannelsPatternLength_1_256, int16_t enabledChannelsPattern[], int PowerManagement_0_2, int chan_id_0_1);
+            // TODO: cmdLine.serial().printf("\r\n 9 channelsPattern... pm=? id=? | len=? -- MAX11131_ScanSampleSetExtClock");
+            //
+            // get MAX11131 Sampleset channel selection pattern parse_strCommandArgs(strCommandArgs);
+            // cmdLine.parse_byteCount_byteList_dec(byteCount, mosiData, MAX_SPI_BYTE_COUNT)
+            // into g_MAX11131_device.enabledChannelsPatternLength_1_256
+            // into g_MAX11131_device.enabledChannelsPattern[0..255]
+            size_t numValues;
+            char valueList[256];
+            if (cmdLine.parse_byteCount_byteList_dec( numValues, valueList, 256))
+            {
+                // first value is the "9" command itself
+                g_MAX11131_device.enabledChannelsPatternLength_1_256 = numValues - 1;
+                // copy valueList[1, ...] into g_MAX11131_device.enabledChannelsPattern[0, ...]
+                for (size_t index = 0; index < (numValues - 1); index++)
+                {
+                    g_MAX11131_device.enabledChannelsPattern[index] = valueList[1 + index];
+                }
+            }
+            //
+            cmdLine.serial().printf("ScanSampleSetExternalClock enabledChannelsPattern:{ ");
+            int index;
+            for (index = 0; index < g_MAX11131_device.enabledChannelsPatternLength_1_256; index++)
+            {
+                //~ Serial.print( ((g_enabledChannelsPattern[index] >> 4) & 0x000F), DEC);
+                //~ Serial.print(" ");
+                cmdLine.serial().printf("AIN%d ", ((g_MAX11131_device.enabledChannelsPattern[index]) & 0x000F));
+            }
+            cmdLine.serial().printf("}");
+            cmdLine.serial().printf(" pm=%d id=%d\r\n", g_MAX11131_device.PowerManagement_0_2,
+                                    g_MAX11131_device.chan_id_0_1);
+            // VERIFY: replace argument with driver global; g_MAX11131_device.PowerManagement_0_2 replaces PowerManagement_0_2
+            // VERIFY: replace argument with driver global; g_MAX11131_device.chan_id_0_1 replaces chan_id_0_1
+            g_MAX11131_device.NumWords = g_MAX11131_device.ScanSampleSetExternalClock();
+            //
+            // Read raw ADC codes from device into AINcode[] and RAW_misoData16[]
+            // @pre one of the MAX11311_Scan functions was called, setting g_MAX11131_device.NumWords
+            g_MAX11131_device.ReadAINcode();
+            // @post RAW_misoData16[index] contains the raw SPI Master-In,Slave-Out data
+            // @post AINcode[NUM_CHANNELS] contains the latest readings in LSBs
+            //
+            AINcode_print_value_externalClock(cmdLine, g_MAX11131_device.NumWords);
+        }
+        break;
+        case 'a': case 'A':
+        {
+            // recommended for hex command codes A0..AF
+            switch (cmdLine[1])
+            {
+                case 't': case 'T':
+#if IGNORE_AT_COMMANDS
+# if HAS_DAPLINK_SERIAL
+                    cmdLine_DAPLINKserial.serial().printf("\r\n ignore AT command \"%s\"\r\n", cmdLine.str());
+# endif // HAS_DAPLINK_SERIAL
+                    // AT command: skip the prompt to avoid confusing modem detector
+                    return;
+#endif // IGNORE_AT_COMMANDS
+            }
+        }
+        break;
+        case 'b': case 'B':
+        {
+            // recommended for hex command codes B0..BF
+        }
+        break;
+        case 'c': case 'C':
+        {
+            // recommended for hex command codes C0..CF
+        }
+        break;
+        case 'd': case 'D':
+        {
+            // recommended for hex command codes D0..DF
+        }
+        break;
+        case 'e': case 'E':
+        {
+            // recommended for hex command codes E0..EF
+        }
+        break;
+        case 'f': case 'F':
+        {
+            // recommended for hex command codes F0..FF
+        }
+        break;
+        case 'x': case 'X':
+        {
+        }
+        break;
+        case 'y': case 'Y':
+        {
+        }
+        break;
+        case 'i': case 'I':
+        {
+            // TODO: cmdLine.serial().printf("\r\n ISc) IUc) IBc) IRc) reconfigure channel single-ended/unipolar/bipolar/range");
+            char strChannelId[3];
+            strChannelId[0] = cmdLine[2];
+            strChannelId[1] = cmdLine[3];
+            strChannelId[2] = '\0';
+            int channelId_0_15 = strtoul(strChannelId, NULL, 10);         // strtol(str, NULL, 10): get decimal value
+            switch (cmdLine[1])
+            {
+                case 's': case 'S':
+                    g_MAX11131_device.Reconfigure_SingleEnded(channelId_0_15);
+                    break;
+                case 'u': case 'U':
+                    g_MAX11131_device.Reconfigure_DifferentialUnipolar(channelId_0_15);
+                    break;
+                case 'b': case 'B':
+                    g_MAX11131_device.Reconfigure_DifferentialBipolarFSVref(channelId_0_15);
+                    break;
+                case 'r': case 'R':
+                    g_MAX11131_device.Reconfigure_DifferentialBipolarFS2Vref(channelId_0_15);
+                    break;
+            }
+            // char cmd1 = strCommandArgs[0];
+            // strCommandArgs.remove(0, 1); // unsigned int index, unsigned int count
+            // // get argument int channelId_0_15
+            // // parse_strCommandArgs(strCommandArgs);
+            // int channelId_0_15 = strtoul(strCommandArgs.c_str(), NULL, 10); // strtol(str, NULL, 10): get decimal value
+            // if (cmd1 == 'S') {
+            //     MAX11131_Reconfigure_SingleEnded(channelId_0_15);
+            // }
+            // else if (cmd1 == 'U') {
+            //     MAX11131_Reconfigure_DifferentialUnipolar(channelId_0_15);
+            // }
+            // else if (cmd1 == 'B') {
+            //     MAX11131_Reconfigure_DifferentialBipolarFSVref(channelId_0_15);
+            // }
+            // else if (cmd1 == 'R') {
+            //     MAX11131_Reconfigure_DifferentialBipolarFS2Vref(channelId_0_15);
+            // }
+        }
+        break;
+        case '@':
+        {
+            // TODO: cmdLine.serial().printf("\r\n @                                      -- print MAX11131 configuration");
+            // print shadow register configuration
+            //
+            cmdLine.serial().printf("0x%4.4x", (g_MAX11131_device.ADC_MODE_CONTROL & 0xFFFF));
+            MAX11131_print_register_verbose(cmdLine, g_MAX11131_device.ADC_MODE_CONTROL);
+            cmdLine.serial().printf("0x%4.4x", (g_MAX11131_device.ADC_CONFIGURATION & 0xFFFF));
+            MAX11131_print_register_verbose(cmdLine, g_MAX11131_device.ADC_CONFIGURATION);
+            cmdLine.serial().printf("0x%4.4x", (g_MAX11131_device.UNIPOLAR & 0xFFFF));
+            MAX11131_print_register_verbose(cmdLine, g_MAX11131_device.UNIPOLAR);
+            cmdLine.serial().printf("0x%4.4x", (g_MAX11131_device.BIPOLAR & 0xFFFF));
+            MAX11131_print_register_verbose(cmdLine, g_MAX11131_device.BIPOLAR);
+            cmdLine.serial().printf("0x%4.4x", (g_MAX11131_device.RANGE & 0xFFFF));
+            MAX11131_print_register_verbose(cmdLine, g_MAX11131_device.RANGE);
+            cmdLine.serial().printf("0x%4.4x", (g_MAX11131_device.CSCAN0 & 0xFFFF));
+            MAX11131_print_register_verbose(cmdLine, g_MAX11131_device.CSCAN0);
+            cmdLine.serial().printf("0x%4.4x", (g_MAX11131_device.CSCAN1 & 0xFFFF));
+            MAX11131_print_register_verbose(cmdLine, g_MAX11131_device.CSCAN1);
+            cmdLine.serial().printf("0x%4.4x", (g_MAX11131_device.SAMPLESET & 0xFFFF));
+            MAX11131_print_register_verbose(cmdLine, g_MAX11131_device.SAMPLESET);
+            //
+            // VERIFY: print shadow SAMPLESET pattern entry
+            int entryIndex;
+            for (entryIndex = 0; entryIndex < g_MAX11131_device.enabledChannelsPatternLength_1_256;
+                 entryIndex += 4)
+            {
+                uint16_t pack4channels = 0;
+                pack4channels |= (((g_MAX11131_device.enabledChannelsPattern[entryIndex + 0]) & 0x0F) << 12);
+                if ((entryIndex + 1) < g_MAX11131_device.enabledChannelsPatternLength_1_256) {
+                    pack4channels |= (((g_MAX11131_device.enabledChannelsPattern[entryIndex + 1]) & 0x0F) << 8);
+                }
+                if ((entryIndex + 2) < g_MAX11131_device.enabledChannelsPatternLength_1_256) {
+                    pack4channels |= (((g_MAX11131_device.enabledChannelsPattern[entryIndex + 2]) & 0x0F) << 4);
+                }
+                if ((entryIndex + 3) < g_MAX11131_device.enabledChannelsPatternLength_1_256) {
+                    pack4channels |= ((g_MAX11131_device.enabledChannelsPattern[entryIndex + 3]) & 0x0F);
+                }
+                //~ SPIwrite16bits(pack4channels);
+                cmdLine.serial().printf("       0x%4.4x", (pack4channels & 0xFFFF));
+                // decode SAMPLESET channel select pattern
+                cmdLine.serial().printf(" SampleSet Entry: AIN%d AIN%d AIN%d AIN%d\r\n",
+                                        ((pack4channels >> 12) & 0x000F),
+                                        ((pack4channels >> 8) & 0x000F),
+                                        ((pack4channels >> 4) & 0x000F),
+                                        ((pack4channels      ) & 0x000F)
+                                        );
+            }
+            //cmdLine.serial().printf("  SAMPLESET enabledChannelsPattern:{ ");
+            //int index;
+            //for (index = 0; index < g_MAX11131_device.enabledChannelsPatternLength_1_256; index++)
+            //{
+            //  //~ cmdLine.serial().printf( ((g_enabledChannelsPattern[index] >> 4) & 0x000F), DEC);
+            //  //~ cmdLine.serial().printf(" ");
+            //  cmdLine.serial().printf("AIN");
+            //  cmdLine.serial().printf( ((g_MAX11131_device.enabledChannelsPattern[index]) & 0x000F), DEC);
+            //  cmdLine.serial().printf(" ");
+            //}
+            //cmdLine.serial().printf("}");
+            //
+            // Menu @) print MAX11131 configuration AND g_MAX11131_device globals
+            //
+            cmdLine.serial().printf("SPI_MOSI_Semantic=%d\r\n", (g_MAX11131_device.SPI_MOSI_Semantic & 0xFFFF));
+            cmdLine.serial().printf("NumWords=%d\r\n", (g_MAX11131_device.NumWords & 0xFFFF));
+            cmdLine.serial().printf("isExternalClock=%d\r\n", (g_MAX11131_device.isExternalClock & 0xFFFF));
+            cmdLine.serial().printf("ScanMode=%d\r\n", (g_MAX11131_device.ScanMode & 0xFFFF));
+            cmdLine.serial().printf("channelNumber_0_15=%d\r\n",
+                                    (g_MAX11131_device.channelNumber_0_15 & 0xFFFF));
+            cmdLine.serial().printf("PowerManagement_0_2=%d\r\n",
+                                    (g_MAX11131_device.PowerManagement_0_2 & 0xFFFF));
+            cmdLine.serial().printf("chan_id_0_1=%d\r\n", (g_MAX11131_device.chan_id_0_1 & 0xFFFF));
+            cmdLine.serial().printf("average_0_4_8_16_32=%d\r\n",
+                                    (g_MAX11131_device.average_0_4_8_16_32 & 0xFFFF));
+            cmdLine.serial().printf("nscan_4_8_12_16=%d\r\n", (g_MAX11131_device.nscan_4_8_12_16 & 0xFFFF));
+            cmdLine.serial().printf("swcnv_0_1=%d\r\n", (g_MAX11131_device.swcnv_0_1 & 0xFFFF));
+            cmdLine.serial().printf("enabledChannelsMask=0x%4.4x\r\n",
+                                    (g_MAX11131_device.enabledChannelsMask & 0xFFFF));
+            //
+            cmdLine.serial().printf("VRef=%5.3fV\r\n", g_MAX11131_device.VRef);
+            // dtostrf width and precision: 3.3V / 1024 LSB = 0.00322265625 volts per LSB
+            //
+        }
+            //case '&':
+            //{
+            //    // TODO: cmdLine.serial().printf("\r\n & -- MAX11131_Example_ScanManual");
+            //}
+            break;
+        case '~':     // TODO: IGNORE_AT_COMMANDS -- ignore ~~~ modem command
+        {
+            // TODO: '~' is not recommended for menu commands, interferes with ssh
+#if IGNORE_AT_COMMANDS
+# if HAS_DAPLINK_SERIAL
+            cmdLine_DAPLINKserial.serial().printf("\r\n ignore AT command \"%s\"\r\n", cmdLine.str());
+# endif // HAS_DAPLINK_SERIAL
+#endif // IGNORE_AT_COMMANDS
+        }
+        break;
+        case '+':     // TODO: IGNORE_AT_COMMANDS -- ignore +++ modem command
+        {
+#if IGNORE_AT_COMMANDS
+# if HAS_DAPLINK_SERIAL
+            cmdLine_DAPLINKserial.serial().printf("\r\n ignore AT command \"%s\"\r\n", cmdLine.str());
+# endif // HAS_DAPLINK_SERIAL
+#endif // IGNORE_AT_COMMANDS
+        }
+        break;
+#endif // APPLICATION_MAX11131
+
+#if APPLICATION_MAX5171 // main_menu_onEOLcommandParser
+        // MAX5171 main_menu_onEOLcommandParser
+        case '0':
+        {
+            // recommended for hex command codes 10..1F
+            //~ cmdLine.serial().printf("\r\n 0 code=? -- CODE");
+            uint16_t code;
+            if (cmdLine.parse_uint16_dec("code", code))
+            {
+            }
+            cmdLine.serial().printf("CODE code=%d", code);
+            g_MAX5171_device.CODE(code);
+        }
+        break;
+        case '4':
+        {
+            // recommended for hex command codes 10..1F
+            //~ cmdLine.serial().printf("\r\n 4 code=? -- CODE_LOAD");
+            uint16_t code;
+            if (cmdLine.parse_uint16_dec("code", code))
+            {
+            }
+            cmdLine.serial().printf("CODE_LOAD code=%d", code);
+            g_MAX5171_device.CODE_LOAD(code);
+        }
+        break;
+        case '8':
+        {
+            // recommended for hex command codes 10..1F
+            //~ cmdLine.serial().printf("\r\n 8 -- LOAD");
+            cmdLine.serial().printf("LOAD");
+            g_MAX5171_device.LOAD();
+        }
+        break;
+        case 'c': case 'C':
+        {
+            // recommended for hex command codes 10..1F
+            //~ cmdLine.serial().printf("\r\n c -- NOP");
+            cmdLine.serial().printf("NOP");
+            g_MAX5171_device.NOP();
+        }
+        break;
+        case 'd': case 'D':
+        {
+            // recommended for hex command codes 10..1F
+            //~ cmdLine.serial().printf("\r\n d -- SHUTDOWN");
+            cmdLine.serial().printf("SHUTDOWN");
+            g_MAX5171_device.SHUTDOWN();
+        }
+        break;
+        case 'e': case 'E':
+        {
+            switch (cmdLine[1])
+            {
+                case '0':
+                {
+                    // recommended for hex command codes 10..1F
+                    //~ cmdLine.serial().printf("\r\n e0 -- UPO_LOW");
+                    cmdLine.serial().printf("UPO_LOW");
+                    g_MAX5171_device.UPO_LOW();
+                }
+                break;
+                case '8':
+                {
+                    // recommended for hex command codes 10..1F
+                    //~ cmdLine.serial().printf("\r\n e8 -- UPO_HIGH");
+                    cmdLine.serial().printf("UPO_HIGH");
+                    g_MAX5171_device.UPO_HIGH();
+                }
+                break;
+            }
+        }
+        break;
+        case 'f': case 'F':
+        {
+            switch (cmdLine[1])
+            {
+                case '0':
+                {
+                    // recommended for hex command codes 10..1F
+                    //~ cmdLine.serial().printf("\r\n f0 -- MODE1_DOUT_SCLK_RISING_EDGE");
+                    cmdLine.serial().printf("MODE1_DOUT_SCLK_RISING_EDGE");
+                    g_MAX5171_device.MODE1_DOUT_SCLK_RISING_EDGE();
+                }
+                break;
+                case '8':
+                {
+                    // recommended for hex command codes 10..1F
+                    //~ cmdLine.serial().printf("\r\n f8 -- MODE0_DOUT_SCLK_FALLING_EDGE");
+                    cmdLine.serial().printf("MODE0_DOUT_SCLK_FALLING_EDGE");
+                    g_MAX5171_device.MODE0_DOUT_SCLK_FALLING_EDGE();
+                }
+                break;
+            }
+        }
+        break;
+        case 'a': case 'A':
+        {
+            // recommended for hex command codes A0..AF
+            switch (cmdLine[1])
+            {
+                case 't': case 'T':
+#if IGNORE_AT_COMMANDS
+# if HAS_DAPLINK_SERIAL
+                    cmdLine_DAPLINKserial.serial().printf("\r\n ignore AT command \"%s\"\r\n", cmdLine.str());
+# endif // HAS_DAPLINK_SERIAL
+                    // AT command: skip the prompt to avoid confusing modem detector
+                    return;
+#endif // IGNORE_AT_COMMANDS
+            }
+        }
+        break;
+        case 'x': case 'X':
+        {
+        }
+        break;
+        case 'y': case 'Y':
+        {
+        }
+        break;
+        case 'z': case 'Z':
+        {
+        }
+        break;
+        case '~':     // TODO: IGNORE_AT_COMMANDS -- ignore ~~~ modem command
+        {
+            // TODO: '~' is not recommended for menu commands, interferes with ssh
+#if IGNORE_AT_COMMANDS
+# if HAS_DAPLINK_SERIAL
+            cmdLine_DAPLINKserial.serial().printf("\r\n ignore AT command \"%s\"\r\n", cmdLine.str());
+# endif // HAS_DAPLINK_SERIAL
+#endif // IGNORE_AT_COMMANDS
+        }
+        break;
+        case '+':     // TODO: IGNORE_AT_COMMANDS -- ignore +++ modem command
+        {
+#if IGNORE_AT_COMMANDS
+# if HAS_DAPLINK_SERIAL
+            cmdLine_DAPLINKserial.serial().printf("\r\n ignore AT command \"%s\"\r\n", cmdLine.str());
+# endif // HAS_DAPLINK_SERIAL
+#endif // IGNORE_AT_COMMANDS
+        }
+        break;
+#endif // APPLICATION_MAX5171
+
+
+#if APPLICATION_MAX11410 // main_menu_onEOLcommandParser
+        // TODO1: MAX11410 main_menu_onEOLcommandParser
+        case '0':
+        {
+            // recommended for hex command codes 00..0F
+            // placeholder: cmdLine.serial().printf("\r\n 3 ch=? code=? -- CODEnLOADn");
+            uint16_t ch = g_MAX5715_device.channelNumber_0_3;
+            uint16_t code;
+            if (cmdLine.parse_uint16_dec("ch", ch))
+            {
+            }
+            if (cmdLine.parse_uint16_dec("code", code))
+            {
+            }
+            if (cmdLine.parse_flag("xyzzy", g_xyzzy_flag, XYZZY_FLAG))
+            {
+                isUpdatedSPIConfig = true;
+            }
+            cmdLine.serial().printf("CODEnLOADn ch=%d code=%d", ch, code);
+            MAX5715_CODEnLOADn(ch, code);
+            cmdLine.serial().printf("\r\n placeholder");
+        }
+        break;
+        case '1':
+        {
+            // recommended for hex command codes 10..1F
+        }
+        break;
+        case '2':
+        {
+            // recommended for hex command codes 20..2F
+        }
+        break;
+        case '3':
+        {
+            // recommended for hex command codes 30..3F
+        }
+        break;
+        case '4':
+        {
+            // recommended for hex command codes 40..4F
+        }
+        break;
+        case '5':
+        {
+            // recommended for hex command codes 50..5F
+        }
+        break;
+        case '6':
+        {
+            // recommended for hex command codes 60..6F
+        }
+        break;
+        case '7':
+        {
+            // recommended for hex command codes 70..7F
+        }
+        break;
+        case '8':
+        {
+            // recommended for hex command codes 80..8F
+        }
+        break;
+        case '9':
+        {
+            // recommended for hex command codes 90..9F
+        }
+        break;
+        case 'a': case 'A':
+        {
+            // recommended for hex command codes A0..AF
+            switch (cmdLine[1])
+            {
+                case 't': case 'T':
+#if IGNORE_AT_COMMANDS
+# if HAS_DAPLINK_SERIAL
+                    cmdLine_DAPLINKserial.serial().printf("\r\n ignore AT command \"%s\"\r\n", cmdLine.str());
+# endif // HAS_DAPLINK_SERIAL
+                    // AT command: skip the prompt to avoid confusing modem detector
+                    return;
+#endif // IGNORE_AT_COMMANDS
+            }
+        }
+        break;
+        case 'b': case 'B':
+        {
+            // recommended for hex command codes B0..BF
+        }
+        break;
+        case 'c': case 'C':
+        {
+            // recommended for hex command codes C0..CF
+        }
+        break;
+        case 'd': case 'D':
+        {
+            // recommended for hex command codes D0..DF
+        }
+        break;
+        case 'e': case 'E':
+        {
+            // recommended for hex command codes E0..EF
+        }
+        break;
+        case 'f': case 'F':
+        {
+            // recommended for hex command codes F0..FF
+        }
+        break;
+        case 'x': case 'X':
+        {
+        }
+        break;
+        case 'y': case 'Y':
+        {
+        }
+        break;
+        case 'z': case 'Z':
+        {
+        }
+        break;
+        case '~':     // TODO: IGNORE_AT_COMMANDS -- ignore ~~~ modem command
+        {
+            // TODO: '~' is not recommended for menu commands, interferes with ssh
+#if IGNORE_AT_COMMANDS
+# if HAS_DAPLINK_SERIAL
+            cmdLine_DAPLINKserial.serial().printf("\r\n ignore AT command \"%s\"\r\n", cmdLine.str());
+# endif // HAS_DAPLINK_SERIAL
+#endif // IGNORE_AT_COMMANDS
+        }
+        break;
+        case '+':     // TODO: IGNORE_AT_COMMANDS -- ignore +++ modem command
+        {
+#if IGNORE_AT_COMMANDS
+# if HAS_DAPLINK_SERIAL
+            cmdLine_DAPLINKserial.serial().printf("\r\n ignore AT command \"%s\"\r\n", cmdLine.str());
+# endif // HAS_DAPLINK_SERIAL
+#endif // IGNORE_AT_COMMANDS
+        }
+        break;
+#endif // APPLICATION_MAX11410
+
+
+#if APPLICATION_MAX12345 // main_menu_onEOLcommandParser
+        case '0':
+        {
+            // recommended for hex command codes 00..0F
+            // placeholder: cmdLine.serial().printf("\r\n 3 ch=? code=? -- CODEnLOADn");
+            uint16_t ch = g_MAX5715_device.channelNumber_0_3;
+            uint16_t code;
+            if (cmdLine.parse_uint16_dec("ch", ch))
+            {
+            }
+            if (cmdLine.parse_uint16_dec("code", code))
+            {
+            }
+            if (cmdLine.parse_flag("xyzzy", g_xyzzy_flag, XYZZY_FLAG))
+            {
+                isUpdatedSPIConfig = true;
+            }
+            cmdLine.serial().printf("CODEnLOADn ch=%d code=%d", ch, code);
+            MAX5715_CODEnLOADn(ch, code);
+            cmdLine.serial().printf("\r\n placeholder");
+        }
+        break;
+        case '1':
+        {
+            // recommended for hex command codes 10..1F
+        }
+        break;
+        case '2':
+        {
+            // recommended for hex command codes 20..2F
+        }
+        break;
+        case '3':
+        {
+            // recommended for hex command codes 30..3F
+        }
+        break;
+        case '4':
+        {
+            // recommended for hex command codes 40..4F
+        }
+        break;
+        case '5':
+        {
+            // recommended for hex command codes 50..5F
+        }
+        break;
+        case '6':
+        {
+            // recommended for hex command codes 60..6F
+        }
+        break;
+        case '7':
+        {
+            // recommended for hex command codes 70..7F
+        }
+        break;
+        case '8':
+        {
+            // recommended for hex command codes 80..8F
+        }
+        break;
+        case '9':
+        {
+            // recommended for hex command codes 90..9F
+        }
+        break;
+        case 'a': case 'A':
+        {
+            // recommended for hex command codes A0..AF
+            switch (cmdLine[1])
+            {
+                case 't': case 'T':
+#if IGNORE_AT_COMMANDS
+# if HAS_DAPLINK_SERIAL
+                    cmdLine_DAPLINKserial.serial().printf("\r\n ignore AT command \"%s\"\r\n", cmdLine.str());
+# endif // HAS_DAPLINK_SERIAL
+                    // AT command: skip the prompt to avoid confusing modem detector
+                    return;
+#endif // IGNORE_AT_COMMANDS
+            }
+        }
+        break;
+        case 'b': case 'B':
+        {
+            // recommended for hex command codes B0..BF
+        }
+        break;
+        case 'c': case 'C':
+        {
+            // recommended for hex command codes C0..CF
+        }
+        break;
+        case 'd': case 'D':
+        {
+            // recommended for hex command codes D0..DF
+        }
+        break;
+        case 'e': case 'E':
+        {
+            // recommended for hex command codes E0..EF
+        }
+        break;
+        case 'f': case 'F':
+        {
+            // recommended for hex command codes F0..FF
+        }
+        break;
+        case 'x': case 'X':
+        {
+        }
+        break;
+        case 'y': case 'Y':
+        {
+        }
+        break;
+        case 'z': case 'Z':
+        {
+        }
+        break;
+        case '~':     // TODO: IGNORE_AT_COMMANDS -- ignore ~~~ modem command
+        {
+            // TODO: '~' is not recommended for menu commands, interferes with ssh
+#if IGNORE_AT_COMMANDS
+# if HAS_DAPLINK_SERIAL
+            cmdLine_DAPLINKserial.serial().printf("\r\n ignore AT command \"%s\"\r\n", cmdLine.str());
+# endif // HAS_DAPLINK_SERIAL
+#endif // IGNORE_AT_COMMANDS
+        }
+        break;
+        case '+':     // TODO: IGNORE_AT_COMMANDS -- ignore +++ modem command
+        {
+#if IGNORE_AT_COMMANDS
+# if HAS_DAPLINK_SERIAL
+            cmdLine_DAPLINKserial.serial().printf("\r\n ignore AT command \"%s\"\r\n", cmdLine.str());
+# endif // HAS_DAPLINK_SERIAL
+#endif // IGNORE_AT_COMMANDS
+        }
+        break;
+#endif // APPLICATION_MAX12345
+
+//#if IGNORE_AT_COMMANDS
+//        // tolerate AT commands, which may be sent during probe
+//        // "AT\r"
+//        // "AT+CGMI\r" -- request manufacturer identification AT+CMGI=?
+//        // "AT+CGMM\r" -- request manufacturer model
+//        // "AT%IPSYS?\r"
+//        // "ATE0\r" -- echo disable
+//        // "ATV1\r" -- verbose result codes OK | ERROR | NO CARRIER
+//        // menu_main() ignore_until_line_end: AT
+//        // menu_main() ignore_until_line_end: AT+CGMI
+//        // menu_main() ignore_until_line_end: AT+CGMM
+//        // menu_main() ignore_until_line_end: AT%IPSYS?
+//        // menu_main() ignore_until_line_end: ATE0
+//        // menu_main() ignore_until_line_end: ATV1
+//        // menu_main() ignore_until_line_end: AT+CMEE=1
+//        // menu_main() ignore_until_line_end: ATX4
+//        // menu_main() ignore_until_line_end: AT&C1
+//        // menu_main() ignore_until_line_end: ATE0
+//        // menu_main() ignore_until_line_end: AT+CMEE=1
+//        // menu_main() ignore_until_line_end: AT+GCAP
+//        // menu_main() ignore_until_line_end: ATI
+//        // menu_main() ignore_until_line_end: AT+CPIN?
+//        // menu_main() ignore_until_line_end: AT+CGMM
+//        case 'A':
+//            // likely unwanted AT command, host probing for a modem.
+//            // ignore everything up to next line end '\r' or '\n'.
+//            //~ ignore_until_line_end = true;
+//# if HAS_DAPLINK_SERIAL
+//            cmdLine_DAPLINKserial.serial().printf("\r\n ignore AT command \"%s\"\r\n", cmdLine.str());
+//# endif // HAS_DAPLINK_SERIAL
+//            //~ goto label_menu_main_idle;
+//            break;
+//#endif // IGNORE_AT_COMMANDS
+        //
+        //
+        // TODO1: add new commands here
+        //
+        default:
+            cmdLine.serial().printf("\r\n unknown command 0x%2.2x \"%s\"\r\n", cmdLine.str()[0], cmdLine.str());
+# if HAS_DAPLINK_SERIAL
+            cmdLine_DAPLINKserial.serial().printf("\r\n unknown command 0x%2.2x \"%s\"\r\n",
+                                                  cmdLine.str()[0], cmdLine.str());
+# endif // HAS_DAPLINK_SERIAL
+    }     // switch (cmdLine[0])
+//
+// print command prompt
+#if APPLICATION_MAX5715 // main_menu_onEOLcommandParser print command prompt
+    cmdLine.serial().printf("\r\nMAX5715 > ");
+#elif APPLICATION_MAX11131 // main_menu_onEOLcommandParser print command prompt
+    cmdLine.serial().printf("\r\nMAX11131 > ");
+#elif APPLICATION_MAX5171 // main_menu_onEOLcommandParser print command prompt
+    cmdLine.serial().printf("\r\nMAX5171 > ");
+#elif APPLICATION_MAX11410 // main_menu_onEOLcommandParser print command prompt
+    cmdLine.serial().printf("\r\nMAX11410 > ");
+#elif APPLICATION_MAX12345 // main_menu_onEOLcommandParser print command prompt
+    cmdLine.serial().printf("\r\nMAX12345 > ");
+#else
+    cmdLine.serial().printf("\r\n> ");
+#endif
+}
+#endif //USE_COMMAND_BUFFER
+
+//--------------------------------------------------
+void InitializeConfiguration()
+{
+
+#if APPLICATION_MAX5715 // InitializeConfiguration
+# if HAS_DAPLINK_SERIAL
+    cmdLine_DAPLINKserial.serial().printf("\r\nMAX5715_Init()");
+# endif
+# if HAS_MICROUSBSERIAL
+    cmdLine_microUSBserial.serial().printf("\r\nMAX5715_Init()");
+# endif
+    int initResult = g_MAX5715_device.Init();     // defined in #include MAX5715.h
+# if HAS_DAPLINK_SERIAL
+    cmdLine_DAPLINKserial.serial().printf("\r\nMAX5715_Init() returned %d\r\n", initResult);
+# endif
+# if HAS_MICROUSBSERIAL
+    cmdLine_microUSBserial.serial().printf("\r\nMAX5715_Init() returned %d\r\n", initResult);
+# endif
+#endif // APPLICATION_MAX5715
+
+#if APPLICATION_MAX11131 // InitializeConfiguration
+# if HAS_DAPLINK_SERIAL
+    cmdLine_DAPLINKserial.serial().printf("\r\nMAX11131_Init()");
+# endif
+# if HAS_MICROUSBSERIAL
+    cmdLine_microUSBserial.serial().printf("\r\nMAX11131_Init()");
+# endif
+    g_MAX11131_device.Init();     // defined in #include MAX11131.h
+#endif // APPLICATION_MAX11131
+
+#if APPLICATION_MAX5171 // InitializeConfiguration
+# if HAS_DAPLINK_SERIAL
+    cmdLine_DAPLINKserial.serial().printf("\r\nMAX5171_Init()");
+# endif
+# if HAS_MICROUSBSERIAL
+    cmdLine_microUSBserial.serial().printf("\r\nMAX5171_Init()");
+# endif
+    int initResult = g_MAX5171_device.Init();     // defined in #include MAX5171.h
+# if HAS_DAPLINK_SERIAL
+    cmdLine_DAPLINKserial.serial().printf("\r\nMAX5171_Init() returned %d\r\n", initResult);
+# endif
+# if HAS_MICROUSBSERIAL
+    cmdLine_microUSBserial.serial().printf("\r\nMAX5171_Init() returned %d\r\n", initResult);
+# endif
+#endif // APPLICATION_MAX5171
+
+#if APPLICATION_MAX11410 // InitializeConfiguration
+# if HAS_DAPLINK_SERIAL
+    cmdLine_DAPLINKserial.serial().printf("\r\nMAX11410_Init()");
+# endif
+# if HAS_MICROUSBSERIAL
+    cmdLine_microUSBserial.serial().printf("\r\nMAX11410_Init()");
+# endif
+    int initResult = g_MAX11410_device.Init();     // defined in #include MAX11410.h
+# if HAS_DAPLINK_SERIAL
+    cmdLine_DAPLINKserial.serial().printf("\r\nMAX11410_Init() returned %d\r\n", initResult);
+# endif
+# if HAS_MICROUSBSERIAL
+    cmdLine_microUSBserial.serial().printf("\r\nMAX11410_Init() returned %d\r\n", initResult);
+# endif
+#endif // APPLICATION_MAX11410
+
+#if APPLICATION_MAX12345 // InitializeConfiguration
+# if HAS_DAPLINK_SERIAL
+    cmdLine_DAPLINKserial.serial().printf("\r\nMAX12345_Init()");
+# endif
+# if HAS_MICROUSBSERIAL
+    cmdLine_microUSBserial.serial().printf("\r\nMAX12345_Init()");
+# endif
+    int initResult = MAX12345_Init();     // defined in #include MAX12345.h
+# if HAS_DAPLINK_SERIAL
+    cmdLine_DAPLINKserial.serial().printf("\r\nMAX12345_Init() returned %d\r\n", initResult);
+# endif
+# if HAS_MICROUSBSERIAL
+    cmdLine_microUSBserial.serial().printf("\r\nMAX12345_Init() returned %d\r\n", initResult);
+# endif
+#endif // APPLICATION_MAX12345
+
+}
+
+//--------------------------------------------------
+// diagnostic rbg led GREEN
+void diagnostic_led_EOF()
+{
+#if USE_LEDS
+    led1 = LED_ON; led2 = LED_ON; led3 = LED_OFF;     // diagnostic rbg led RED+GREEN=YELLOW
+    // TODO1: mbed-os-5.11: [Warning] 'static osStatus rtos::Thread::wait(uint32_t)' is deprecated: Static methods only affecting current thread cause confusion. Replaced by ThisThread::sleep_for. [since mbed-os-5.10] [-Wdeprecated-declarations]
+    ThisThread::sleep_for(250); // [since mbed-os-5.10] vs Thread::wait(250);
+    led1 = LED_OFF; led2 = LED_ON; led3 = LED_OFF;     // diagnostic rbg led GREEN
+    ThisThread::sleep_for(250); // [since mbed-os-5.10] vs Thread::wait(250);
+    led1 = LED_ON; led2 = LED_ON; led3 = LED_OFF;     // diagnostic rbg led RED+GREEN=YELLOW
+    ThisThread::sleep_for(250); // [since mbed-os-5.10] vs Thread::wait(250);
+    led1 = LED_OFF; led2 = LED_ON; led3 = LED_OFF;     // diagnostic rbg led GREEN
+    ThisThread::sleep_for(250); // [since mbed-os-5.10] vs Thread::wait(250);
+#endif // USE_LEDS
+}
+
+//--------------------------------------------------
+// Support commands that get handled immediately w/o waiting for EOL
+// handled as immediate command, do not append to buffer
+void on_immediate_0x21() // Unicode (U+0021) ! EXCLAMATION MARK
+{
+#if USE_LEDS
+    led1 = LED_OFF; led2 = LED_OFF; led3 = LED_ON;     // diagnostic rbg led BLUE
+#endif // USE_LEDS
+    InitializeConfiguration();
+    ThisThread::sleep_for(125); // [since mbed-os-5.10] vs Thread::wait(125);
+}
+
+//--------------------------------------------------
+// Support commands that get handled immediately w/o waiting for EOL
+// handled as immediate command, do not append to buffer
+void on_immediate_0x7b() // Unicode (U+007B) { LEFT CURLY BRACKET
+{
+    //~ led1 = LED_OFF; led2 = LED_ON; led3 = LED_OFF;     // diagnostic rbg led GREEN
+    //~ InitializeConfiguration();
+    //~ ThisThread::sleep_for(125); // [since mbed-os-5.10] vs Thread::wait(125);
+#if HAS_BUTTON2_DEMO_INTERRUPT
+    onButton2FallingEdge();
+#endif
+}
+
+//--------------------------------------------------
+// Support commands that get handled immediately w/o waiting for EOL
+// handled as immediate command, do not append to buffer
+void on_immediate_0x7d() // Unicode (U+007D) } RIGHT CURLY BRACKET
+{
+    //~ led1 = LED_OFF; led2 = LED_ON; led3 = LED_OFF;     // diagnostic rbg led GREEN
+    //~ InitializeConfiguration();
+    //~ ThisThread::sleep_for(125); // [since mbed-os-5.10] vs Thread::wait(125);
+#if HAS_BUTTON1_DEMO_INTERRUPT
+    onButton1FallingEdge();
+#endif
+}
+
+//--------------------------------------------------
+// based on example code: https://os.mbed.com/docs/v5.7/reference/pwmout.html
+int main()
+{
+//#ifdef SCOPE_TRIG_PIN
+//    //pinMode(SCOPE_TRIG_PIN, OUTPUT);
+//    scopeTrigPinP11 = 0; // digitalWrite(SCOPE_TRIG_PIN, LOW);
+//    scopeTrigPinP11 = 1; // digitalWrite(SCOPE_TRIG_PIN, HIGH);
+//#endif // SCOPE_TRIG_PIN
+
+    // Configure serial ports
+#if defined(TARGET_MAX32630)
+    // Note: DAPLINKserial interferes with the timer tick interrupt. Try faster baud rate?
+    DAPLINKserial.baud(115200);     // default 9600 baud
+    //microUSBserial.baud(9600); // class USBSerial has no baud function
+#  if HAS_DAPLINK_SERIAL
+    DAPLINKserial.printf("\r\n\r\nDAPLINK_SERIAL: main() startup\r\n");
+#  endif
+//--------------------------------------------------
+#elif defined(TARGET_MAX32625MBED)
+    // MAX32625MBED crash if DAPLINKserial.baud(anything other than 9600 baud)
+    // xxx DAPLINKserial.baud(115200); // default 9600 baud
+    //microUSBserial.baud(9600); // class USBSerial has no baud function
+#  if HAS_DAPLINK_SERIAL
+    DAPLINKserial.printf("\r\n\r\nDAPLINK_SERIAL: main() startup\r\n");
+#  endif
+//--------------------------------------------------
+#elif defined(TARGET_LPC1768)
+    microUSBserial.baud(115200);     // default 9600 baud
+#else
+    // unknown target
+#endif
+#if USE_COMMAND_BUFFER
+# if HAS_MICROUSBSERIAL
+    cmdLine_microUSBserial.clear();
+    //~ cmdLine_microUSBserial.serial().printf("\r\n cmdLine_microUSBserial.serial().printf test\r\n");
+    cmdLine_microUSBserial.onEOLcommandParser = main_menu_onEOLcommandParser;
+    /// @todo CmdLine::set_immediate_handler(char, functionPointer_void_void_on_immediate_0x21);
+    cmdLine_microUSBserial.on_immediate_0x21 = on_immediate_0x21;
+    cmdLine_microUSBserial.on_immediate_0x7b = on_immediate_0x7b;
+    cmdLine_microUSBserial.on_immediate_0x7d = on_immediate_0x7d;
+# endif
+# if HAS_DAPLINK_SERIAL
+    cmdLine_DAPLINKserial.clear();
+    //~ cmdLine_DAPLINKserial.serial().printf("\r\n cmdLine_DAPLINKserial.serial().printf test\r\n");
+    cmdLine_DAPLINKserial.onEOLcommandParser = main_menu_onEOLcommandParser;
+    /// @todo CmdLine::set_immediate_handler(char, functionPointer_void_void_on_immediate_0x21);
+    cmdLine_DAPLINKserial.on_immediate_0x21 = on_immediate_0x21;
+    cmdLine_DAPLINKserial.on_immediate_0x7b = on_immediate_0x7b;
+    cmdLine_DAPLINKserial.on_immediate_0x7d = on_immediate_0x7d;
+# endif
+#endif
+
+
+    print_banner();
+
+//#ifdef SCOPE_TRIG_PIN
+//    scopePinP12 = 0;
+//    scopePinP12 = 1;
+//#endif // SCOPE_TRIG_PIN
+
+#if HAS_BUTTON1_DEMO_INTERRUPT
+# if HAS_BUTTON1_DEMO_INTERRUPT_POLLING
+# else
+    button1.fall(&onButton1FallingEdge);
+# endif
+#endif // HAS_BUTTON1_DEMO_INTERRUPT
+#if HAS_BUTTON2_DEMO_INTERRUPT
+# if HAS_BUTTON1_DEMO_INTERRUPT_POLLING
+# else
+    button2.fall(&onButton2FallingEdge);
+# endif
+#endif // HAS_BUTTON2_DEMO_INTERRUPT
+
+#if defined(TARGET_MAX32630)
+    // TODO1: timer tick needs to be the highest priority (priority 0, the default).
+    // TODO1: DAPLINKserial interferes with the timer tick interrupt.
+    // Lower the priority of the serial port interrupts to avoid disrupting motor operation.
+    NVIC_SetPriority(UART0_IRQn, 2);     // reservedBlueToothSerial(P0_1, P0_0) // 0=highest priority; 1=lower
+    NVIC_SetPriority(UART1_IRQn, 2);     // DAPLINKserial(P2_1, P2_0) // 0=highest priority; 1=lower
+    NVIC_SetPriority(UART2_IRQn, 2);     // reservedSerial(P3_1, P3_0) // 0=highest priority; 1=lower
+    NVIC_SetPriority(UART3_IRQn, 2);     // reservedSerial(P5_4, P5_3) // 0=highest priority; 1=lower
+    NVIC_SetPriority(GPIO_P0_IRQn, 2);     // 0=highest priority; 1=lower
+    NVIC_SetPriority(GPIO_P1_IRQn, 2);     // 0=highest priority; 1=lower
+    NVIC_SetPriority(GPIO_P2_IRQn, 2);     // 0=highest priority; 1=lower
+    NVIC_SetPriority(GPIO_P3_IRQn, 2);     // 0=highest priority; 1=lower
+    NVIC_SetPriority(GPIO_P4_IRQn, 2);     // 0=highest priority; 1=lower
+    NVIC_SetPriority(GPIO_P5_IRQn, 2);     // 0=highest priority; 1=lower
+    NVIC_SetPriority(GPIO_P6_IRQn, 2);     // 0=highest priority; 1=lower
+    NVIC_SetPriority(GPIO_P7_IRQn, 2);     // 0=highest priority; 1=lower
+    NVIC_SetPriority(GPIO_P8_IRQn, 2);     // 0=highest priority; 1=lower
+    //~ NVIC_SetPriority(RTC0_IRQn, 0); // 0=highest priority; 1=lower
+    //~ NVIC_SetPriority(RTC3_IRQn, 0); // 0=highest priority; 1=lower
+    //~ NVIC_SetPriority(US_TIMER_IRQn, 0); // 0=highest priority; 1=lower
+#endif
+
+#if HAS_SPI
+    // spi init
+    // mode | POL PHA
+    // -----+--------
+    //   0  |  0   0
+    //   1  |  0   1
+    //   2  |  1   0
+    //   3  |  1   1
+    //~ spi.format(8,0); // int bits_must_be_8, int mode=0_3 CPOL=0,CPHA=0 rising edge (initial default)
+    //~ spi.format(8,1); // int bits_must_be_8, int mode=0_3 CPOL=0,CPHA=1 falling edge (initial default)
+    //~ spi.format(8,2); // int bits_must_be_8, int mode=0_3 CPOL=1,CPHA=0 falling edge (initial default)
+    //~ spi.format(8,3); // int bits_must_be_8, int mode=0_3 CPOL=1,CPHA=1 rising edge (initial default)
+    //
+    //~ spi.frequency(1000000); // int SCLK_Hz=1000000 = 1MHz (initial default)
+    //~ spi.frequency(9600000); // int SCLK_Hz=9600000 = 9.6MHz = 96MHz/10
+    //~ spi.frequency(10666666); // int SCLK_Hz=10666666 = 10.6MHz = 96MHz/9
+    //~ spi.frequency(12000000); // int SCLK_Hz=12000000 = 12MHz = 96MHz/8
+    //~ spi.frequency(13714286); // int SCLK_Hz=13714286 = 13.7MHz = 96MHz/7
+    //~ spi.frequency(16000000); // int SCLK_Hz=16000000 = 16MHz = 96MHz/6
+    //~ spi.frequency(19200000); // int SCLK_Hz=19200000 = 19.2MHz = 96MHz/5
+    //~ spi.frequency(24000000); // int SCLK_Hz=24000000 = 24MHz = 96MHz/4
+    //~ spi.frequency(32000000); // int SCLK_Hz=32000000 = 32MHz = 96MHz/3
+    //~ spi.frequency(48000000); // int SCLK_Hz=48000000 = 48MHz = 96MHz/2
+    // unspecified SPI device
+    spi.format(8,g_SPI_dataMode);     // int bits_must_be_8, int mode=0_3 CPOL=0,CPHA=0 rising edge (initial default)
+    spi.frequency(g_SPI_SCLK_Hz);     // int SCLK_Hz=1000000 = 1MHz (initial default)
+    spi_cs = 1;
+#endif
+
+#if HAS_I2C
+// i2c init
+// declare in narrower scope: MAX32625MBED I2C i2cMaster(...)
+//    i2cMaster.frequency(g_I2C_SCL_Hz);
+#else
+    // Ensure that the unused I2C pins do not interfere with analog inputs A4 and A5
+#if HAS_digitalInOut14
+    // DigitalInOut digitalInOut14(P1_6, PIN_INPUT, PullUp, 1); // P1_6 TARGET_MAX32635MBED A4/SDA (10pin digital connector)
+    digitalInOut14.input();
+#endif
+#if HAS_digitalInOut15
+    // DigitalInOut digitalInOut15(P1_7, PIN_INPUT, PullUp, 1); // P1_7 TARGET_MAX32635MBED A5/SCL (10pin digital connector)
+    digitalInOut15.input();
+#endif
+#if HAS_digitalInOut16
+    // DigitalInOut mode can be one of PullUp, PullDown, PullNone, OpenDrain
+    // PullUp-->3.4V, PullDown-->1.7V, PullNone-->3.5V, OpenDrain-->0.00V
+    //DigitalInOut digitalInOut16(P3_4, PIN_INPUT, OpenDrain, 0); // P3_4 TARGET_MAX32635MBED A4/SDA (6pin analog connector)
+    digitalInOut16.input();
+#endif
+#if HAS_digitalInOut17
+    //DigitalInOut digitalInOut17(P3_5, PIN_INPUT, OpenDrain, 0); // P3_5 TARGET_MAX32635MBED A5/SCL (6pin analog connector)
+    digitalInOut17.input();
+#endif
+#endif
+
+#if USE_LEDS
+#if defined(TARGET_MAX32630)
+    led1 = LED_ON; led2 = LED_OFF; led3 = LED_OFF;     // diagnostic rbg led RED
+    ThisThread::sleep_for(125); // [since mbed-os-5.10] vs Thread::wait(125);
+    led1 = LED_OFF; led2 = LED_ON; led3 = LED_OFF;     // diagnostic rbg led GREEN
+    ThisThread::sleep_for(125); // [since mbed-os-5.10] vs Thread::wait(125);
+    led1 = LED_OFF; led2 = LED_OFF; led3 = LED_ON;     // diagnostic rbg led BLUE
+    ThisThread::sleep_for(125); // [since mbed-os-5.10] vs Thread::wait(125);
+    led1 = LED_ON; led2 = LED_ON; led3 = LED_ON;     // diagnostic rbg led RED+GREEN+BLUE=WHITE
+    ThisThread::sleep_for(125); // [since mbed-os-5.10] vs Thread::wait(125);
+    led1 = LED_OFF; led2 = LED_ON; led3 = LED_ON;     // diagnostic rbg led GREEN+BLUE=CYAN
+    ThisThread::sleep_for(125); // [since mbed-os-5.10] vs Thread::wait(125);
+    led1 = LED_ON; led2 = LED_OFF; led3 = LED_ON;     // diagnostic rbg led RED+BLUE=MAGENTA
+    ThisThread::sleep_for(125); // [since mbed-os-5.10] vs Thread::wait(125);
+    led1 = LED_ON; led2 = LED_ON; led3 = LED_OFF;     // diagnostic rbg led RED+GREEN=YELLOW
+    ThisThread::sleep_for(125); // [since mbed-os-5.10] vs Thread::wait(125);
+    led1 = LED_OFF; led2 = LED_OFF; led3 = LED_OFF;     // diagnostic rbg led BLACK
+    ThisThread::sleep_for(125); // [since mbed-os-5.10] vs Thread::wait(125);
+#elif defined(TARGET_MAX32625MBED)
+    led1 = LED_ON; led2 = LED_OFF; led3 = LED_OFF;     // diagnostic rbg led RED
+    ThisThread::sleep_for(125); // [since mbed-os-5.10] vs Thread::wait(125);
+    led1 = LED_OFF; led2 = LED_ON; led3 = LED_OFF;     // diagnostic rbg led GREEN
+    ThisThread::sleep_for(125); // [since mbed-os-5.10] vs Thread::wait(125);
+    led1 = LED_OFF; led2 = LED_OFF; led3 = LED_ON;     // diagnostic rbg led BLUE
+    ThisThread::sleep_for(125); // [since mbed-os-5.10] vs Thread::wait(125);
+    led1 = LED_ON; led2 = LED_ON; led3 = LED_ON;     // diagnostic rbg led RED+GREEN+BLUE=WHITE
+    ThisThread::sleep_for(125); // [since mbed-os-5.10] vs Thread::wait(125);
+    led1 = LED_OFF; led2 = LED_ON; led3 = LED_ON;     // diagnostic rbg led GREEN+BLUE=CYAN
+    ThisThread::sleep_for(125); // [since mbed-os-5.10] vs Thread::wait(125);
+    led1 = LED_ON; led2 = LED_OFF; led3 = LED_ON;     // diagnostic rbg led RED+BLUE=MAGENTA
+    ThisThread::sleep_for(125); // [since mbed-os-5.10] vs Thread::wait(125);
+    led1 = LED_ON; led2 = LED_ON; led3 = LED_OFF;     // diagnostic rbg led RED+GREEN=YELLOW
+    ThisThread::sleep_for(125); // [since mbed-os-5.10] vs Thread::wait(125);
+    led1 = LED_OFF; led2 = LED_OFF; led3 = LED_OFF;     // diagnostic rbg led BLACK
+    ThisThread::sleep_for(125); // [since mbed-os-5.10] vs Thread::wait(125);
+#else // not defined(TARGET_LPC1768 etc.)
+    led1 = LED_ON;
+    led2 = LED_OFF;
+    led3 = LED_OFF;
+    led4 = LED_OFF;
+    ThisThread::sleep_for(75); // [since mbed-os-5.10] vs Thread::wait(75);
+    //led1 = LED_ON;
+    led2 = LED_ON;
+    ThisThread::sleep_for(75); // [since mbed-os-5.10] vs Thread::wait(75);
+    led1 = LED_OFF;
+    //led2 = LED_ON;
+    led3 = LED_ON;
+    ThisThread::sleep_for(75); // [since mbed-os-5.10] vs Thread::wait(75);
+    led2 = LED_OFF;
+    //led3 = LED_ON;
+    led4 = LED_ON;
+    ThisThread::sleep_for(75); // [since mbed-os-5.10] vs Thread::wait(75);
+    led3 = LED_OFF;
+    led4 = LED_ON;
+    //
+#endif // target definition
+#endif
+
+    // cmd_TE();
+
+#if USE_LEDS
+    rgb_led.white();     // diagnostic rbg led RED+GREEN+BLUE=WHITE
+#endif // USE_LEDS
+    InitializeConfiguration();
+
+    while (1) {
+#if HAS_BUTTON1_DEMO_INTERRUPT_POLLING
+        // avoid runtime error on button1 press [mbed-os-5.11]
+        // instead of using InterruptIn, use DigitalIn and poll in main while(1)
+# if HAS_BUTTON1_DEMO_INTERRUPT
+        static int button1_value_prev = 1;
+        static int button1_value_now = 1;
+        button1_value_prev = button1_value_now;
+        button1_value_now = button1.read();
+        if ((button1_value_prev - button1_value_now) == 1)
+        {
+            // on button1 falling edge (button1 press)
+            onButton1FallingEdge();
+        }
+# endif // HAS_BUTTON1_DEMO_INTERRUPT
+# if HAS_BUTTON2_DEMO_INTERRUPT
+        static int button2_value_prev = 1;
+        static int button2_value_now = 1;
+        button2_value_prev = button2_value_now;
+        button2_value_now = button2.read();
+        if ((button2_value_prev - button2_value_now) == 1)
+        {
+            // on button2 falling edge (button2 press)
+            onButton2FallingEdge();
+        }
+# endif // HAS_BUTTON2_DEMO_INTERRUPT
+#endif
+#if USE_COMMAND_BUFFER
+        //cmdLine_update();
+        //--------------------------------------------------
+        // GREEN = DAPLINKserial
+        //~ led1 = LED_OFF; led2 = LED_ON; led3 = LED_OFF; // diagnostic rbg led GREEN
+    # if HAS_DAPLINK_SERIAL
+        if (DAPLINKserial.readable()) {
+            cmdLine_DAPLINKserial.append(DAPLINKserial.getc());
+        }
+    # endif // HAS_DAPLINK_SERIAL
+            //--------------------------------------------------
+            // BLUE = reading ADC
+            //~ led1 = LED_OFF; led2 = LED_OFF; led3 = LED_ON; // diagnostic rbg led BLUE
+            // CS=%d) set comTickLimit %d..%d CSA) comTickLimit is set by AIN0
+            //~ if (is_comTickLimit_from_AIN0) {
+            //~ update_comTickLimit_from_AIN0_AIN4();
+            //~ }
+            //--------------------------------------------------
+            // YELLOW = microUSBserial
+            //~ led1 = LED_ON; led2 = LED_ON; led3 = LED_OFF; // diagnostic rbg led RED+GREEN=YELLOW
+    # if HAS_MICROUSBSERIAL
+        if (microUSBserial.readable()) {
+            int c = microUSBserial.getc();
+            cmdLine_microUSBserial.append(c);
+#if IGNORE_AT_COMMANDS
+# if HAS_DAPLINK_SERIAL
+            cmdLine_DAPLINKserial.serial().printf("%c", c);
+# endif // HAS_DAPLINK_SERIAL
+#endif // IGNORE_AT_COMMANDS
+            //
+        }
+    # endif // HAS_MICROUSBSERIAL
+            //--------------------------------------------------
+            // MAGENTA = reading ADC
+            //~ led1 = LED_ON; led2 = LED_OFF; led3 = LED_ON; // diagnostic rbg led RED+BLUE=MAGENTA
+            // CP=%d) set pwmCompare %d..%d CPA) PWM is set by AIN1
+            //~ if (is_pwmCompare_from_AIN1) {
+            //~ update_pwmCompare_from_AIN1_AIN5();
+            //~ }
+            //--------------------------------------------------
+            // CYAN = other while loop stuff?
+            //~ led1 = LED_OFF; led2 = LED_ON; led3 = LED_ON; // diagnostic rbg led GREEN+BLUE=CYAN
+            //~ 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
+#else // USE_COMMAND_BUFFER
+        //
+        // character echo demo stuff; sandbox
+        //
+        // char* gets(char* buf, int size); // equivalent to char *gets_s( char *str, rsize_t n )
+        // Reads characters from stdin until a newline is found or end-of-file occurs.
+        // Writes only at most n-1 characters into the array pointed to by str,
+        // and always writes the terminating null character (unless str is a null pointer).
+        // The newline character, is discarded and not written to the buffer.
+        if (gets(line_buffer, sizeof(line_buffer)))
+        {
+            puts(line_buffer);
+        }
+
+        // serial port demo -- echo from DAPLINKserial to microUSBserial
+        #if HAS_DAPLINK_SERIAL
+        if (DAPLINKserial.readable()) {
+            int c = DAPLINKserial.getc();
+            led2 = (c & 1);
+            #if HAS_DAPLINK_SERIAL
+            DAPLINKserial.putc(c);
+            #endif
+            #if HAS_MICROUSBSERIAL
+            microUSBserial.putc(c);
+            #endif
+            // command processing
+            if (c == '?') {
+                print_banner();
+            }
+        }
+        #endif // HAS_DAPLINK_SERIAL
+               // serial port demo -- echo from microUSBserial to DAPLINKserial
+        #if HAS_MICROUSBSERIAL
+        if (microUSBserial.readable()) {
+            int c = microUSBserial.getc();
+            led1 = (c & 1);
+            #if HAS_DAPLINK_SERIAL
+            DAPLINKserial.putc(c);
+            #endif
+            microUSBserial.putc(c);
+            // command processing
+            if (c == '?') {
+                print_banner();
+            }
+        }
+        #endif // HAS_MICROUSBSERIAL
+#endif // USE_COMMAND_BUFFER
+    }     // while(1)
+}