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

Dependencies:   MaximTinyTester MAX11131 CmdLine MAX541 USBDevice

Revision:
11:38b95a59de02
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Test_Menu_MAX11131.cpp	Wed Jun 26 01:05:56 2019 +0000
@@ -0,0 +1,677 @@
+// /*******************************************************************************
+// * 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 "MAX11131.h"
+#include "CmdLine.h"
+
+//--------------------------------------------------
+// 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
+
+extern MAX11131 g_MAX11131_device; // defined in main.cpp
+extern void AINcode_print_value_externalClock(CmdLine& cmdLine, int nWords); // defined in main.cpp
+extern void AINcode_print_value_chanID(CmdLine& cmdLine, int nWords); // defined in main.cpp
+extern void AINcode_print_value_chanID_mean(CmdLine& cmdLine, int nWords); // defined in main.cpp
+extern void MAX11131_print_register_verbose(CmdLine& cmdLine, int16_t registerData); // defined in main.cpp
+
+bool MAX11131_menu_onEOLcommandParser(CmdLine & cmdLine)
+{
+    switch (cmdLine[0])
+    {
+        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);
+            }
+            return true; // command was handled by MAX11131
+        }
+        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);
+            return true; // command was handled by MAX11131
+        }
+        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);
+            return true; // command was handled by MAX11131
+        }
+        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);
+            return true; // command was handled by MAX11131
+        }
+        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);
+            return true; // command was handled by MAX11131
+        }
+        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);
+            return true; // command was handled by MAX11131
+        }
+        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);
+            return true; // command was handled by MAX11131
+        }
+        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);
+            return true; // command was handled by MAX11131
+        }
+        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);
+            return true; // command was handled by MAX11131
+        }
+        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);
+            return true; // command was handled by MAX11131
+        }
+        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 false; // command not handled
+#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);
+            // }
+            return true; // command was handled by MAX11131
+        }
+        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
+            //
+            return true; // command was handled by MAX11131
+        }
+            //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;
+    } // end switch (cmdLine[0])
+    return false; // command not handled
+} // end bool MAX11131_menu_onEOLcommandParser(CmdLine & cmdLine)
+