Mark Underwood / Mbed OS MAX11043_Serial_Tester

Dependencies:   MaximTinyTester CmdLine MAX541 USBDevice

Files at this revision

API Documentation at this revision

Comitter:
whismanoid
Date:
Mon Jun 10 07:53:42 2019 +0000
Child:
1:40369075c365
Commit message:
based on sandbox monster, need remove unrelated products; does online ide not support c++11 lambda expressions?

Changed in this revision

CmdLine.lib Show annotated file Show diff for this revision Revisions of this file
MAX541.lib Show annotated file Show diff for this revision Revisions of this file
MAX5715.lib Show annotated file Show diff for this revision Revisions of this file
MaximTinyTester.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-os.lib Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CmdLine.lib	Mon Jun 10 07:53:42 2019 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/whismanoid/code/CmdLine/#0f702da53f2a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MAX541.lib	Mon Jun 10 07:53:42 2019 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/teams/MaximIntegrated/code/MAX541/#4836afabd85b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MAX5715.lib	Mon Jun 10 07:53:42 2019 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/teams/MaximIntegrated/code/MAX5715/#7a5d38577aa1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MaximTinyTester.lib	Mon Jun 10 07:53:42 2019 +0000
@@ -0,0 +1,1 @@
+MaximTinyTester#93d4119d3f14
--- /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)
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-os.lib	Mon Jun 10 07:53:42 2019 +0000
@@ -0,0 +1,1 @@
+https://github.com/ARMmbed/mbed-os/#73f096399b4cda1f780b140c87afad9446047432