Internal_Datalogger but with USB support removed (for MAX40108 Demo board), proof of concept that MAX32625 can be used successfully with VDDB(USB) left unpowered, as long as the USB library is not used.

Dependencies:   max32625pico CmdLine

Revision:
15:37c83ec50ea0
Parent:
14:d4092094dbfe
Child:
16:819c5aaf5271
--- a/DataLogger_Internal.cpp	Fri Mar 05 08:20:02 2021 +0000
+++ b/DataLogger_Internal.cpp	Wed Mar 31 19:12:49 2021 -0700
@@ -35,6 +35,7 @@
 // *******************************************************************************
 #ifndef MAX40108_DEMO
 #define MAX40108_DEMO 1
+#define HAS_DAPLINK_SERIAL 1
 #endif // MAX40108_DEMO
 //---------- CODE GENERATOR: DataLogHelloCppCodeList
 // CODE GENERATOR: example code includes
@@ -366,7 +367,7 @@
 //
 //--------------------------------------------------
 #elif defined(TARGET_MAX32625PICO)
-#warning "TARGET_MAX32625PICO not previously tested; need to define pins..."
+// #warning "TARGET_MAX32625PICO not previously tested; need to define pins..."
 #include "max32625pico.h"
 // configure MAX32625PICO VDDIOH mode, and I/O voltages for DIP pins and SWD pins
 MAX32625PICO pico(
@@ -391,7 +392,7 @@
     );
 //#define USE_LEDS 0 ?
 #define analogIn4_IS_HIGH_RANGE_OF_analogIn0 1
-#warning "TARGET_MAX32625PICO not previously tested; need to verify ADC_FULL_SCALE_VOLTAGE..."
+// #warning "TARGET_MAX32625PICO not previously tested; need to verify ADC_FULL_SCALE_VOLTAGE..."
 const float ADC_FULL_SCALE_VOLTAGE = 1.200;
 //
 //--------------------------------------------------
@@ -684,6 +685,152 @@
     DigitalInOut digitalInOut17(P3_5, PIN_INPUT, OpenDrain, 0); // P3_5 TARGET_MAX32635MBED A5/SCL (6pin analog connector)
 #endif
 //--------------------------------------------------
+#elif defined(TARGET_MAX32625PICO)
+// TARGET=MAX32625PICO ARM Cortex-M4F 96MHz 512kB Flash 160kB SRAM
+//             +-------------[microUSB]-------------+
+//             |           [27]D+ D-[26]            |
+//             |                                    |
+//             |           [BUTTON P2_7]            |
+//             |  P2_4 LED_R P2_5 LED_G P2_6 LED_B  |
+//             |                                    |
+//         1V8 | [11] 1.8V  MAX32625PICO   GND [10] | GND
+//         3V3 | [12] 3.3V                 +5V [09] | 5V0
+// SPI CS   D7 | [13] P0_7 CS      s-ssel P4_7 [08] | D15
+// SPI MISO D6 | [14] P0_6 MISO    s-miso P4_6 [07] | D14
+// SPI MOSI D5 | [15] P0_5 MOSI    s-mosi P4_5 [06] | D13
+// SPI SCLK D4 | [16] P0_4 SCLK    s-sclk P4_4 [05] | D12
+//          D3 | [17] P0_3 RTS        SCL P1_7 [04] | SCL/D17
+//          D2 | [18] P0_2 CTS        SDA P1_6 [03] | SDA/D16
+//       TX/D1 | [19] P0_1 TX0           AIN_2 [02] | A2
+//       RX/D0 | [20] P0_0 RX0           AIN_0 [01] | A0/A4
+//             |                                    |
+//             |                  DAPLINK           |
+//             |  J3   p3_3 p3_2 p3_0 p3_1 p3_7     |
+//             |  DAP  [  ] [  ] [RX2][TX2][  ]     |
+//             |  TOP  [  ] [  ] [  ] [  ] [  ]     |
+//             |    AIN1/A5 gnd  gnd   nc  AIN3     |
+//             |       IOH                 1-wire   |
+//             |                                    |
+//             |NO USE RST       P2_0      P2_1     |
+//             |BOTTOM [  ] [  ] [RX1][  ] [TX1]    |
+//             |       RST  SWC  GND  SWD  1V8      |
+//             |BOTTOM [21] [22] [23] [24] [25]     |
+//             +------------------------------------+
+#if MAX40108_DEMO
+// MAX40108 demo p2: D0..D7 = P0_0..P0_7; D8..15 = P4_0..P4_7; D16/D17=I2C
+#endif
+// 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
+//
+#if MAX40108_DEMO
+// avoid resource conflict D0,D1 alternate function as RX/TX
+    #define HAS_digitalInOut0 0
+    #define HAS_digitalInOut1 0
+#else
+    #define HAS_digitalInOut0 1
+    #define HAS_digitalInOut1 1 // P0_1 TARGET_MAX32625PICO D1
+#endif
+#if APPLICATION_MAX11131
+// avoid resource conflict D2 alternate function as interrupt input
+    #define HAS_digitalInOut2 0
+#else
+    #define HAS_digitalInOut2 1
+#endif
+    #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_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_MAX32625PICO D0
+#endif
+#if HAS_digitalInOut1
+    DigitalInOut digitalInOut1(P0_1, PIN_INPUT, PullUp, 1); // P0_1 TARGET_MAX32625PICO D1
+#endif
+#if HAS_digitalInOut2
+    DigitalInOut digitalInOut2(P0_2, PIN_INPUT, PullUp, 1); // P0_2 TARGET_MAX32625PICO D2
+#endif
+#if HAS_digitalInOut3
+    DigitalInOut digitalInOut3(P0_3, PIN_INPUT, PullUp, 1); // P0_3 TARGET_MAX32625PICO D3
+#endif
+#if HAS_digitalInOut4
+    DigitalInOut digitalInOut4(P0_4, PIN_INPUT, PullUp, 1); // P0_4 TARGET_MAX32625PICO D4
+#endif
+#if HAS_digitalInOut5
+    DigitalInOut digitalInOut5(P0_5, PIN_INPUT, PullUp, 1); // P0_5 TARGET_MAX32625PICO D5
+#endif
+#if HAS_digitalInOut6
+    DigitalInOut digitalInOut6(P0_6, PIN_INPUT, PullUp, 1); // P0_6 TARGET_MAX32625PICO D6
+#endif
+#if HAS_digitalInOut7
+    DigitalInOut digitalInOut7(P0_7, PIN_INPUT, PullUp, 1); // P0_7 TARGET_MAX32625PICO D7
+#endif
+#if HAS_digitalInOut8
+    DigitalInOut digitalInOut8(P4_0, PIN_INPUT, PullUp, 1); // P4_0 TARGET_MAX32625PICO D8
+#endif
+#if HAS_digitalInOut9
+    DigitalInOut digitalInOut9(P4_1, PIN_INPUT, PullUp, 1); // P4_1 TARGET_MAX32625PICO D9
+#endif
+#if HAS_digitalInOut10
+    DigitalInOut digitalInOut10(P4_2, PIN_INPUT, PullUp, 1); // P4_2 TARGET_MAX32625PICO D10
+#endif
+#if HAS_digitalInOut11
+    DigitalInOut digitalInOut11(P4_3, PIN_INPUT, PullUp, 1); // P4_3 TARGET_MAX32625PICO D11
+#endif
+#if HAS_digitalInOut12
+    DigitalInOut digitalInOut12(P4_4, PIN_INPUT, PullUp, 1); // P4_4 TARGET_MAX32625PICO D12
+#endif
+#if HAS_digitalInOut13
+    DigitalInOut digitalInOut13(P4_5, PIN_INPUT, PullUp, 1); // P4_5 TARGET_MAX32625PICO D13
+#endif
+#if HAS_digitalInOut14
+    DigitalInOut digitalInOut14(P4_6, PIN_INPUT, PullUp, 1); // P4_6 TARGET_MAX32625PICO D14
+#endif
+#if HAS_digitalInOut15
+    DigitalInOut digitalInOut15(P4_7, PIN_INPUT, PullUp, 1); // P4_7 TARGET_MAX32625PICO D15
+#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
+    DigitalInOut digitalInOut16(P1_6, PIN_INPUT, OpenDrain, 1); // P1_6 TARGET_MAX32635PICO A4/SDA
+#endif
+#if HAS_digitalInOut17
+    // Ensure that the unused I2C pins do not interfere with analog inputs A4 and A5
+    DigitalInOut digitalInOut17(P1_7, PIN_INPUT, OpenDrain, 1); // P1_7 TARGET_MAX32635PICO A5/SCL
+#endif
+//--------------------------------------------------
 #elif defined(TARGET_NUCLEO_F446RE) || defined(TARGET_NUCLEO_F401RE)
     #define HAS_digitalInOut0 0
     #define HAS_digitalInOut1 0
@@ -2428,6 +2575,525 @@
 #endif // USE_CMDLINE_MENUS support CmdLine command menus
 
 #if USE_CMDLINE_MENUS // support CmdLine command menus
+
+//--------------------------------------------------
+void pinsMonitor_submenu_onEOLcommandParser(CmdLine& cmdLine)
+{
+    // % diagnostic commands submenu
+    // %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
+    //
+    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
+            serial.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_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 'D': case 'd':
+                    // %SD -- SPI diagnostic messages enable
+                    if (g_MAX5719_device.onSPIprint) {
+                        g_MAX5719_device.onSPIprint = NULL;
+                        // no g_MAX5719_device.loop_limit property; device_has_property(Device, 'loop_limit') != None is false
+                    }
+                    else {
+                        void onSPIprint_handler(size_t byteCount, uint8_t mosiData[], uint8_t misoData[]);
+                        g_MAX5719_device.onSPIprint = onSPIprint_handler;
+                        // no g_MAX5719_device.loop_limit property; device_has_property(Device, 'loop_limit') is false
+                    }
+                    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])
+} // end void pinsMonitor_submenu_onEOLcommandParser(CmdLine & cmdLine)
+#endif // USE_CMDLINE_MENUS support CmdLine command menus
+
+#if USE_CMDLINE_MENUS // support CmdLine command menus
 //--------------------------------------------------
 void main_menu_onEOLcommandParser(CmdLine& cmdLine)
 {
@@ -2509,7 +3175,7 @@
         }
         break;
 #endif // USE_SELFTEST
-#if 0 // APPLICATION_ArduinoPinsMonitor
+#if 1 // APPLICATION_ArduinoPinsMonitor
         case '%':
         {
             pinsMonitor_submenu_onEOLcommandParser(cmdLine);
@@ -2655,6 +3321,7 @@
                     break;
                 }
                 if (rx_string_length >= g_auxSerialCom_rx_max_count) {
+// [Warning] comparison between signed and unsigned integer expressions 
                     cmdLine.serial().printf("\r\n  rx_max_count %d bytes", g_auxSerialCom_rx_max_count);
                     break;
                 }