Maxim Integrated MAX11131 SPI 12-bit 16-channel ADC with SampleSet

Dependents:   MAX11131BOB_Tester MAX11131BOB_12bit_16ch_SampleSet_SPI_ADC MAX11131BOB_Serial_Tester

MAX11131.h

Committer:
whismanoid
Date:
2021-06-06
Revision:
11:eaaf13fe381e
Parent:
10:92aedaa14cce

File content as of revision 11:eaaf13fe381e:

// /*******************************************************************************
// * Copyright (C) 2021 Maxim Integrated Products, Inc., All Rights Reserved.
// *
// * Permission is hereby granted, free of charge, to any person obtaining a
// * copy of this software and associated documentation files (the "Software"),
// * to deal in the Software without restriction, including without limitation
// * the rights to use, copy, modify, merge, publish, distribute, sublicense,
// * and/or sell copies of the Software, and to permit persons to whom the
// * Software is furnished to do so, subject to the following conditions:
// *
// * The above copyright notice and this permission notice shall be included
// * in all copies or substantial portions of the Software.
// *
// * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
// * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// * OTHER DEALINGS IN THE SOFTWARE.
// *
// * Except as contained in this notice, the name of Maxim Integrated
// * Products, Inc. shall not be used except as stated in the Maxim Integrated
// * Products, Inc. Branding Policy.
// *
// * The mere transfer of this software does not imply any licenses
// * of trade secrets, proprietary technology, copyrights, patents,
// * trademarks, maskwork rights, or any other form of intellectual
// * property whatsoever. Maxim Integrated Products, Inc. retains all
// * ownership rights.
// *******************************************************************************
// */
// *********************************************************************
// @file MAX11131.h
// *********************************************************************
// Header file
// DO NOT EDIT; except areas designated "CUSTOMIZE". Automatically generated file.
// generated by XMLSystemOfDevicesToMBED.py
// System Name = ExampleSystem
// System Description = Device driver example
// Device Name = MAX11131
// Device Description = 3Msps, Low-Power, Serial SPI 12-Bit, 16-Channel, Differential/Single-Ended Input, SAR ADC
// Device DeviceBriefDescription = 12-bit 3Msps 16-ch ADC
// Device Manufacturer = Maxim Integrated
// Device PartNumber = MAX11131ATI+
// Device RegValue_Width = DataWidth16bit_HL
//
// ADC MaxOutputDataRate = 3Msps
// ADC NumChannels = 16
// ADC ResolutionBits = 12
//
// SPI CS = ActiveLow
// SPI FrameStart = CS
// SPI CPOL = 1
// SPI CPHA = 1
// SPI MOSI and MISO Data are both stable on Rising edge of SCLK
// SPI SCLK Idle High
// SPI SCLKMaxMHz = 48
// SPI SCLKMinMHz = 0.48
//


// Prevent multiple declaration
#ifndef __MAX11131_H__
#define __MAX11131_H__

// standard include for target platform -- Platform_Include_Boilerplate
#include "mbed.h"
// Platforms:
//   - MAX32625MBED
//      - supports mbed-os-5.11, requires USBDevice library
//      - add https://developer.mbed.org/teams/MaximIntegrated/code/USBDevice/
//      - remove max32630fthr library (if present)
//      - remove MAX32620FTHR library (if present)
//   - MAX32600MBED
//      - Please note the last supported version is Mbed OS 6.3.
//      - remove max32630fthr library (if present)
//      - remove MAX32620FTHR library (if present)
//      - Windows 10 note:  Don't connect HDK until you are ready to load new firmware into the board.
//   - NUCLEO_F446RE
//      - remove USBDevice library
//      - remove max32630fthr library (if present)
//      - remove MAX32620FTHR library (if present)
//   - NUCLEO_F401RE
//      - remove USBDevice library
//      - remove max32630fthr library (if present)
//      - remove MAX32620FTHR library (if present)
//   - MAX32630FTHR
//      - #include "max32630fthr.h"
//      - add http://developer.mbed.org/teams/MaximIntegrated/code/max32630fthr/
//      - remove MAX32620FTHR library (if present)
//   - MAX32620FTHR
//      - #include "MAX32620FTHR.h"
//      - remove max32630fthr library (if present)
//      - add https://os.mbed.com/teams/MaximIntegrated/code/MAX32620FTHR/
//      - not tested yet
//   - MAX32625PICO
//      - #include "max32625pico.h"
//      - add https://os.mbed.com/users/switches/code/max32625pico/
//      - remove max32630fthr library (if present)
//      - remove MAX32620FTHR library (if present)
//      - not tested yet
//      - see https://os.mbed.com/users/switches/code/max32625pico/
//      - see https://os.mbed.com/users/switches/code/PICO_board_demo/
//      - see https://os.mbed.com/users/switches/code/PICO_USB_I2C_SPI/
//      - see https://os.mbed.com/users/switches/code/SerialInterface/
//      - Note: To load the MAX32625PICO firmware, hold the button while
//        connecting the USB cable, then copy firmware bin file 
//        to the MAINTENANCE drive.
//      - see https://os.mbed.com/platforms/MAX32625PICO/
//      - see https://os.mbed.com/teams/MaximIntegrated/wiki/MAX32625PICO-Firmware-Updates
//
// end Platform_Include_Boilerplate

//----------------------------------------
// Global setting for all channels: ADC_CONFIGURATION.REFSEL
//
// CUSTOMIZE: select one of the following options
// either by uncommenting in this file or define at the project level
//--------------------
// external single-ended reference
//~ #define REFSEL_0 	1
//
//--------------------
// external differential reference (For the 16-channel chips: channel AIN15 is unavailable, the pin is assigned to REF-.)
//~ #define REFSEL_1 	1
//
//--------------------
//
// Default settings if not defined at project level
#ifndef REFSEL_0
# ifndef REFSEL_1
#  define REFSEL_0 	1
#  define REFSEL_1 	0
# endif // REFSEL_1
#endif // REFSEL_0
//
// (optional diagnostic) pragma message the active setting
#if REFSEL_0
//~ #  pragma message("REFSEL_0: external single-ended reference")
#endif // REFSEL_0
#if REFSEL_1
//~ #  pragma message("REFSEL_1: external differential reference (For the 16-channel chips: channel AIN15 is unavailable, the pin is assigned to REF-.)")
#endif // REFSEL_1
//
// Validate the REFSEL_0 setting
#if REFSEL_0
# if REFSEL_1
#  error("cannot have both REFSEL_0 and REFSEL_1; choose one")
# endif // REFSEL_1
#endif // REFSEL_0

//----------------------------------------
// Global setting for all channels: UNIPOLAR.PDIFF_COMM
//
// CUSTOMIZE: select one of the following options
// either by uncommenting in this file or define at the project level
//--------------------
// all single-ended channels use GND as common
//~ #define PDIFF_COMM_0 	1
//
//--------------------
// all single-ended channels are pseudo-differential with REF- as common
//~ #define PDIFF_COMM_1 	1
//
//--------------------
//
// Default settings if not defined at project level
#ifndef PDIFF_COMM_0
# ifndef PDIFF_COMM_1
#  define PDIFF_COMM_0 	1
#  define PDIFF_COMM_1 	0
# endif // PDIFF_COMM_1
#endif // PDIFF_COMM_0
//
// (optional diagnostic) pragma message the active setting
#if PDIFF_COMM_0
//~ #  pragma message("PDIFF_COMM_0: all single-ended channels use GND as common")
#endif // PDIFF_COMM_0
#if PDIFF_COMM_1
//~ #  pragma message("PDIFF_COMM_1: all single-ended channels are pseudo-differential with REF- as common")
#endif // PDIFF_COMM_1
//
// Validate the PDIFF_COMM_0 setting
#if PDIFF_COMM_0
# if PDIFF_COMM_1
#  error("cannot have both PDIFF_COMM_0 and PDIFF_COMM_1; choose one")
# endif // PDIFF_COMM_1
#endif // PDIFF_COMM_0

//----------------------------------------
// ADC Channels AIN0, AIN1
//
// CUSTOMIZE: select one of the following options
// either by uncommenting in this file or define at the project level
//--------------------
// ADC Channels AIN0, AIN1 = Differential Bipolar
// Full Scale = 2 * VREF
// Voltage per LSB count = VREF/2048
// AIN0, AIN1 are a Differential pair using Bipolar transfer function with range (+/-)Vref
// AIN0 voltage must always be between 0 and VREF.
// AIN1 voltage must always be between 0 and VREF.
//
//~ #define AIN_0_1_DifferentialBipolarFS2Vref 	1
//
//--------------------
// ADC Channels AIN0, AIN1 = Differential Bipolar
// Full Scale = VREF
// Voltage per LSB count = VREF/2048
// AIN0, AIN1 are a Differential pair using Bipolar transfer function with range (+/-)(1/2)Vref
// AIN0 voltage must always be between 0 and VREF.
// AIN1 voltage must always be between 0 and VREF.
//
//~ #define AIN_0_1_DifferentialBipolarFSVref 	1
//
//--------------------
// ADC Channels AIN0, AIN1 = Differential Unipolar (AIN0 > AIN1)
// Full Scale = VREF
// Voltage per LSB count = VREF/2048
// AIN0, AIN1 are a Differential pair using Unipolar transfer function.
// AIN0 voltage must always be between 0 and VREF.
// AIN1 voltage must always be between 0 and VREF.
//
//~ #define AIN_0_1_DifferentialUnipolar 	1
//
//--------------------
// ADC Channels AIN0, AIN1 = Both Single-Ended, Unipolar
// Full Scale = VREF
// Voltage per LSB count = VREF/2048
// AIN0 is a Single-Ended input using Unipolar transfer function.
// AIN1 is a Single-Ended input using Unipolar transfer function.
// If PDIFF_COM_1, both are Pseudo-Differential with REF- as common.
// AIN0 voltage must always be between 0 and VREF.
// AIN1 voltage must always be between 0 and VREF.
//
//~ #define AIN_0_1_SingleEnded 	1
//
//--------------------
//
// Default settings if not defined at project level
#ifndef AIN_0_1_DifferentialBipolarFS2Vref
# ifndef AIN_0_1_DifferentialBipolarFSVref
#  ifndef AIN_0_1_DifferentialUnipolar
#   ifndef AIN_0_1_SingleEnded
#    define AIN_0_1_DifferentialBipolarFS2Vref 	0
#    define AIN_0_1_DifferentialBipolarFSVref 	0
#    define AIN_0_1_DifferentialUnipolar 	0
#    define AIN_0_1_SingleEnded 	1
#   endif // AIN_0_1_SingleEnded
#  endif // AIN_0_1_DifferentialUnipolar
# endif // AIN_0_1_DifferentialBipolarFSVref
#endif // AIN_0_1_DifferentialBipolarFS2Vref
//
// (optional diagnostic) pragma message the active setting
#if AIN_0_1_DifferentialBipolarFS2Vref
//~ #  pragma message("AIN_0_1_DifferentialBipolarFS2Vref: ADC Channels AIN0, AIN1 = Differential Bipolar")
#endif // AIN_0_1_DifferentialBipolarFS2Vref
#if AIN_0_1_DifferentialBipolarFSVref
//~ #  pragma message("AIN_0_1_DifferentialBipolarFSVref: ADC Channels AIN0, AIN1 = Differential Bipolar")
#endif // AIN_0_1_DifferentialBipolarFSVref
#if AIN_0_1_DifferentialUnipolar
//~ #  pragma message("AIN_0_1_DifferentialUnipolar: ADC Channels AIN0, AIN1 = Differential Unipolar (AIN0 > AIN1)")
#endif // AIN_0_1_DifferentialUnipolar
#if AIN_0_1_SingleEnded
//~ #  pragma message("AIN_0_1_SingleEnded: ADC Channels AIN0, AIN1 = Both Single-Ended, Unipolar")
#endif // AIN_0_1_SingleEnded
//
// Validate the AIN_0_1_DifferentialBipolarFS2Vref setting
#if AIN_0_1_DifferentialBipolarFS2Vref
# if AIN_0_1_DifferentialBipolarFSVref
#  error("cannot have both AIN_0_1_DifferentialBipolarFS2Vref and AIN_0_1_DifferentialBipolarFSVref; choose one")
# endif // AIN_0_1_DifferentialBipolarFSVref
# if AIN_0_1_DifferentialUnipolar
#  error("cannot have both AIN_0_1_DifferentialBipolarFS2Vref and AIN_0_1_DifferentialUnipolar; choose one")
# endif // AIN_0_1_DifferentialUnipolar
# if AIN_0_1_SingleEnded
#  error("cannot have both AIN_0_1_DifferentialBipolarFS2Vref and AIN_0_1_SingleEnded; choose one")
# endif // AIN_0_1_SingleEnded
#endif // AIN_0_1_DifferentialBipolarFS2Vref
//
// Validate the AIN_0_1_DifferentialBipolarFSVref setting
#if AIN_0_1_DifferentialBipolarFSVref
# if AIN_0_1_DifferentialUnipolar
#  error("cannot have both AIN_0_1_DifferentialBipolarFSVref and AIN_0_1_DifferentialUnipolar; choose one")
# endif // AIN_0_1_DifferentialUnipolar
# if AIN_0_1_SingleEnded
#  error("cannot have both AIN_0_1_DifferentialBipolarFSVref and AIN_0_1_SingleEnded; choose one")
# endif // AIN_0_1_SingleEnded
#endif // AIN_0_1_DifferentialBipolarFSVref
//
// Validate the AIN_0_1_DifferentialUnipolar setting
#if AIN_0_1_DifferentialUnipolar
# if AIN_0_1_SingleEnded
#  error("cannot have both AIN_0_1_DifferentialUnipolar and AIN_0_1_SingleEnded; choose one")
# endif // AIN_0_1_SingleEnded
#endif // AIN_0_1_DifferentialUnipolar

//----------------------------------------
// ADC Channels AIN2, AIN3
//
// CUSTOMIZE: select one of the following options
// either by uncommenting in this file or define at the project level
//--------------------
// ADC Channels AIN2, AIN3 = Differential Bipolar
// Full Scale = 2 * VREF
// Voltage per LSB count = VREF/2048
// AIN2, AIN3 are a Differential pair using Bipolar transfer function with range (+/-)Vref
// AIN2 voltage must always be between 0 and VREF.
// AIN3 voltage must always be between 0 and VREF.
//
//~ #define AIN_2_3_DifferentialBipolarFS2Vref 	1
//
//--------------------
// ADC Channels AIN2, AIN3 = Differential Bipolar
// Full Scale = VREF
// Voltage per LSB count = VREF/2048
// AIN2, AIN3 are a Differential pair using Bipolar transfer function with range (+/-)(1/2)Vref
// AIN2 voltage must always be between 0 and VREF.
// AIN3 voltage must always be between 0 and VREF.
//
//~ #define AIN_2_3_DifferentialBipolarFSVref 	1
//
//--------------------
// ADC Channels AIN2, AIN3 = Differential Unipolar (AIN2 > AIN3)
// Full Scale = VREF
// Voltage per LSB count = VREF/2048
// AIN2, AIN3 are a Differential pair using Unipolar transfer function.
// AIN2 voltage must always be between 0 and VREF.
// AIN3 voltage must always be between 0 and VREF.
//
//~ #define AIN_2_3_DifferentialUnipolar 	1
//
//--------------------
// ADC Channels AIN2, AIN3 = Both Single-Ended, Unipolar
// Full Scale = VREF
// Voltage per LSB count = VREF/2048
// AIN2 is a Single-Ended input using Unipolar transfer function.
// AIN3 is a Single-Ended input using Unipolar transfer function.
// If PDIFF_COM_1, both are Pseudo-Differential with REF- as common.
// AIN2 voltage must always be between 0 and VREF.
// AIN3 voltage must always be between 0 and VREF.
//
//~ #define AIN_2_3_SingleEnded 	1
//
//--------------------
//
// Default settings if not defined at project level
#ifndef AIN_2_3_DifferentialBipolarFS2Vref
# ifndef AIN_2_3_DifferentialBipolarFSVref
#  ifndef AIN_2_3_DifferentialUnipolar
#   ifndef AIN_2_3_SingleEnded
#    define AIN_2_3_DifferentialBipolarFS2Vref 	0
#    define AIN_2_3_DifferentialBipolarFSVref 	0
#    define AIN_2_3_DifferentialUnipolar 	0
#    define AIN_2_3_SingleEnded 	1
#   endif // AIN_2_3_SingleEnded
#  endif // AIN_2_3_DifferentialUnipolar
# endif // AIN_2_3_DifferentialBipolarFSVref
#endif // AIN_2_3_DifferentialBipolarFS2Vref
//
// (optional diagnostic) pragma message the active setting
#if AIN_2_3_DifferentialBipolarFS2Vref
//~ #  pragma message("AIN_2_3_DifferentialBipolarFS2Vref: ADC Channels AIN2, AIN3 = Differential Bipolar")
#endif // AIN_2_3_DifferentialBipolarFS2Vref
#if AIN_2_3_DifferentialBipolarFSVref
//~ #  pragma message("AIN_2_3_DifferentialBipolarFSVref: ADC Channels AIN2, AIN3 = Differential Bipolar")
#endif // AIN_2_3_DifferentialBipolarFSVref
#if AIN_2_3_DifferentialUnipolar
//~ #  pragma message("AIN_2_3_DifferentialUnipolar: ADC Channels AIN2, AIN3 = Differential Unipolar (AIN2 > AIN3)")
#endif // AIN_2_3_DifferentialUnipolar
#if AIN_2_3_SingleEnded
//~ #  pragma message("AIN_2_3_SingleEnded: ADC Channels AIN2, AIN3 = Both Single-Ended, Unipolar")
#endif // AIN_2_3_SingleEnded
//
// Validate the AIN_2_3_DifferentialBipolarFS2Vref setting
#if AIN_2_3_DifferentialBipolarFS2Vref
# if AIN_2_3_DifferentialBipolarFSVref
#  error("cannot have both AIN_2_3_DifferentialBipolarFS2Vref and AIN_2_3_DifferentialBipolarFSVref; choose one")
# endif // AIN_2_3_DifferentialBipolarFSVref
# if AIN_2_3_DifferentialUnipolar
#  error("cannot have both AIN_2_3_DifferentialBipolarFS2Vref and AIN_2_3_DifferentialUnipolar; choose one")
# endif // AIN_2_3_DifferentialUnipolar
# if AIN_2_3_SingleEnded
#  error("cannot have both AIN_2_3_DifferentialBipolarFS2Vref and AIN_2_3_SingleEnded; choose one")
# endif // AIN_2_3_SingleEnded
#endif // AIN_2_3_DifferentialBipolarFS2Vref
//
// Validate the AIN_2_3_DifferentialBipolarFSVref setting
#if AIN_2_3_DifferentialBipolarFSVref
# if AIN_2_3_DifferentialUnipolar
#  error("cannot have both AIN_2_3_DifferentialBipolarFSVref and AIN_2_3_DifferentialUnipolar; choose one")
# endif // AIN_2_3_DifferentialUnipolar
# if AIN_2_3_SingleEnded
#  error("cannot have both AIN_2_3_DifferentialBipolarFSVref and AIN_2_3_SingleEnded; choose one")
# endif // AIN_2_3_SingleEnded
#endif // AIN_2_3_DifferentialBipolarFSVref
//
// Validate the AIN_2_3_DifferentialUnipolar setting
#if AIN_2_3_DifferentialUnipolar
# if AIN_2_3_SingleEnded
#  error("cannot have both AIN_2_3_DifferentialUnipolar and AIN_2_3_SingleEnded; choose one")
# endif // AIN_2_3_SingleEnded
#endif // AIN_2_3_DifferentialUnipolar

//----------------------------------------
// ADC Channels AIN4, AIN5
//
// CUSTOMIZE: select one of the following options
// either by uncommenting in this file or define at the project level
//--------------------
// ADC Channels AIN4, AIN5 = Differential Bipolar
// Full Scale = 2 * VREF
// Voltage per LSB count = VREF/2048
// AIN4, AIN5 are a Differential pair using Bipolar transfer function with range (+/-)Vref
// AIN4 voltage must always be between 0 and VREF.
// AIN5 voltage must always be between 0 and VREF.
//
//~ #define AIN_4_5_DifferentialBipolarFS2Vref 	1
//
//--------------------
// ADC Channels AIN4, AIN5 = Differential Bipolar
// Full Scale = VREF
// Voltage per LSB count = VREF/2048
// AIN4, AIN5 are a Differential pair using Bipolar transfer function with range (+/-)(1/2)Vref
// AIN4 voltage must always be between 0 and VREF.
// AIN5 voltage must always be between 0 and VREF.
//
//~ #define AIN_4_5_DifferentialBipolarFSVref 	1
//
//--------------------
// ADC Channels AIN4, AIN5 = Differential Unipolar (AIN4 > AIN5)
// Full Scale = VREF
// Voltage per LSB count = VREF/2048
// AIN4, AIN5 are a Differential pair using Unipolar transfer function.
// AIN4 voltage must always be between 0 and VREF.
// AIN5 voltage must always be between 0 and VREF.
//
//~ #define AIN_4_5_DifferentialUnipolar 	1
//
//--------------------
// ADC Channels AIN4, AIN5 = Both Single-Ended, Unipolar
// Full Scale = VREF
// Voltage per LSB count = VREF/2048
// AIN4 is a Single-Ended input using Unipolar transfer function.
// AIN5 is a Single-Ended input using Unipolar transfer function.
// If PDIFF_COM_1, both are Pseudo-Differential with REF- as common.
// AIN4 voltage must always be between 0 and VREF.
// AIN5 voltage must always be between 0 and VREF.
//
//~ #define AIN_4_5_SingleEnded 	1
//
//--------------------
//
// Default settings if not defined at project level
#ifndef AIN_4_5_DifferentialBipolarFS2Vref
# ifndef AIN_4_5_DifferentialBipolarFSVref
#  ifndef AIN_4_5_DifferentialUnipolar
#   ifndef AIN_4_5_SingleEnded
#    define AIN_4_5_DifferentialBipolarFS2Vref 	0
#    define AIN_4_5_DifferentialBipolarFSVref 	0
#    define AIN_4_5_DifferentialUnipolar 	0
#    define AIN_4_5_SingleEnded 	1
#   endif // AIN_4_5_SingleEnded
#  endif // AIN_4_5_DifferentialUnipolar
# endif // AIN_4_5_DifferentialBipolarFSVref
#endif // AIN_4_5_DifferentialBipolarFS2Vref
//
// (optional diagnostic) pragma message the active setting
#if AIN_4_5_DifferentialBipolarFS2Vref
//~ #  pragma message("AIN_4_5_DifferentialBipolarFS2Vref: ADC Channels AIN4, AIN5 = Differential Bipolar")
#endif // AIN_4_5_DifferentialBipolarFS2Vref
#if AIN_4_5_DifferentialBipolarFSVref
//~ #  pragma message("AIN_4_5_DifferentialBipolarFSVref: ADC Channels AIN4, AIN5 = Differential Bipolar")
#endif // AIN_4_5_DifferentialBipolarFSVref
#if AIN_4_5_DifferentialUnipolar
//~ #  pragma message("AIN_4_5_DifferentialUnipolar: ADC Channels AIN4, AIN5 = Differential Unipolar (AIN4 > AIN5)")
#endif // AIN_4_5_DifferentialUnipolar
#if AIN_4_5_SingleEnded
//~ #  pragma message("AIN_4_5_SingleEnded: ADC Channels AIN4, AIN5 = Both Single-Ended, Unipolar")
#endif // AIN_4_5_SingleEnded
//
// Validate the AIN_4_5_DifferentialBipolarFS2Vref setting
#if AIN_4_5_DifferentialBipolarFS2Vref
# if AIN_4_5_DifferentialBipolarFSVref
#  error("cannot have both AIN_4_5_DifferentialBipolarFS2Vref and AIN_4_5_DifferentialBipolarFSVref; choose one")
# endif // AIN_4_5_DifferentialBipolarFSVref
# if AIN_4_5_DifferentialUnipolar
#  error("cannot have both AIN_4_5_DifferentialBipolarFS2Vref and AIN_4_5_DifferentialUnipolar; choose one")
# endif // AIN_4_5_DifferentialUnipolar
# if AIN_4_5_SingleEnded
#  error("cannot have both AIN_4_5_DifferentialBipolarFS2Vref and AIN_4_5_SingleEnded; choose one")
# endif // AIN_4_5_SingleEnded
#endif // AIN_4_5_DifferentialBipolarFS2Vref
//
// Validate the AIN_4_5_DifferentialBipolarFSVref setting
#if AIN_4_5_DifferentialBipolarFSVref
# if AIN_4_5_DifferentialUnipolar
#  error("cannot have both AIN_4_5_DifferentialBipolarFSVref and AIN_4_5_DifferentialUnipolar; choose one")
# endif // AIN_4_5_DifferentialUnipolar
# if AIN_4_5_SingleEnded
#  error("cannot have both AIN_4_5_DifferentialBipolarFSVref and AIN_4_5_SingleEnded; choose one")
# endif // AIN_4_5_SingleEnded
#endif // AIN_4_5_DifferentialBipolarFSVref
//
// Validate the AIN_4_5_DifferentialUnipolar setting
#if AIN_4_5_DifferentialUnipolar
# if AIN_4_5_SingleEnded
#  error("cannot have both AIN_4_5_DifferentialUnipolar and AIN_4_5_SingleEnded; choose one")
# endif // AIN_4_5_SingleEnded
#endif // AIN_4_5_DifferentialUnipolar

//----------------------------------------
// ADC Channels AIN6, AIN7
//
// CUSTOMIZE: select one of the following options
// either by uncommenting in this file or define at the project level
//--------------------
// ADC Channels AIN6, AIN7 = Differential Bipolar
// Full Scale = 2 * VREF
// Voltage per LSB count = VREF/2048
// AIN6, AIN7 are a Differential pair using Bipolar transfer function with range (+/-)Vref
// AIN6 voltage must always be between 0 and VREF.
// AIN7 voltage must always be between 0 and VREF.
//
//~ #define AIN_6_7_DifferentialBipolarFS2Vref 	1
//
//--------------------
// ADC Channels AIN6, AIN7 = Differential Bipolar
// Full Scale = VREF
// Voltage per LSB count = VREF/2048
// AIN6, AIN7 are a Differential pair using Bipolar transfer function with range (+/-)(1/2)Vref
// AIN6 voltage must always be between 0 and VREF.
// AIN7 voltage must always be between 0 and VREF.
//
//~ #define AIN_6_7_DifferentialBipolarFSVref 	1
//
//--------------------
// ADC Channels AIN6, AIN7 = Differential Unipolar (AIN6 > AIN7)
// Full Scale = VREF
// Voltage per LSB count = VREF/2048
// AIN6, AIN7 are a Differential pair using Unipolar transfer function.
// AIN6 voltage must always be between 0 and VREF.
// AIN7 voltage must always be between 0 and VREF.
//
//~ #define AIN_6_7_DifferentialUnipolar 	1
//
//--------------------
// ADC Channels AIN6, AIN7 = Both Single-Ended, Unipolar
// Full Scale = VREF
// Voltage per LSB count = VREF/2048
// AIN6 is a Single-Ended input using Unipolar transfer function.
// AIN7 is a Single-Ended input using Unipolar transfer function.
// If PDIFF_COM_1, both are Pseudo-Differential with REF- as common.
// AIN6 voltage must always be between 0 and VREF.
// AIN7 voltage must always be between 0 and VREF.
//
//~ #define AIN_6_7_SingleEnded 	1
//
//--------------------
//
// Default settings if not defined at project level
#ifndef AIN_6_7_DifferentialBipolarFS2Vref
# ifndef AIN_6_7_DifferentialBipolarFSVref
#  ifndef AIN_6_7_DifferentialUnipolar
#   ifndef AIN_6_7_SingleEnded
#    define AIN_6_7_DifferentialBipolarFS2Vref 	0
#    define AIN_6_7_DifferentialBipolarFSVref 	0
#    define AIN_6_7_DifferentialUnipolar 	0
#    define AIN_6_7_SingleEnded 	1
#   endif // AIN_6_7_SingleEnded
#  endif // AIN_6_7_DifferentialUnipolar
# endif // AIN_6_7_DifferentialBipolarFSVref
#endif // AIN_6_7_DifferentialBipolarFS2Vref
//
// (optional diagnostic) pragma message the active setting
#if AIN_6_7_DifferentialBipolarFS2Vref
//~ #  pragma message("AIN_6_7_DifferentialBipolarFS2Vref: ADC Channels AIN6, AIN7 = Differential Bipolar")
#endif // AIN_6_7_DifferentialBipolarFS2Vref
#if AIN_6_7_DifferentialBipolarFSVref
//~ #  pragma message("AIN_6_7_DifferentialBipolarFSVref: ADC Channels AIN6, AIN7 = Differential Bipolar")
#endif // AIN_6_7_DifferentialBipolarFSVref
#if AIN_6_7_DifferentialUnipolar
//~ #  pragma message("AIN_6_7_DifferentialUnipolar: ADC Channels AIN6, AIN7 = Differential Unipolar (AIN6 > AIN7)")
#endif // AIN_6_7_DifferentialUnipolar
#if AIN_6_7_SingleEnded
//~ #  pragma message("AIN_6_7_SingleEnded: ADC Channels AIN6, AIN7 = Both Single-Ended, Unipolar")
#endif // AIN_6_7_SingleEnded
//
// Validate the AIN_6_7_DifferentialBipolarFS2Vref setting
#if AIN_6_7_DifferentialBipolarFS2Vref
# if AIN_6_7_DifferentialBipolarFSVref
#  error("cannot have both AIN_6_7_DifferentialBipolarFS2Vref and AIN_6_7_DifferentialBipolarFSVref; choose one")
# endif // AIN_6_7_DifferentialBipolarFSVref
# if AIN_6_7_DifferentialUnipolar
#  error("cannot have both AIN_6_7_DifferentialBipolarFS2Vref and AIN_6_7_DifferentialUnipolar; choose one")
# endif // AIN_6_7_DifferentialUnipolar
# if AIN_6_7_SingleEnded
#  error("cannot have both AIN_6_7_DifferentialBipolarFS2Vref and AIN_6_7_SingleEnded; choose one")
# endif // AIN_6_7_SingleEnded
#endif // AIN_6_7_DifferentialBipolarFS2Vref
//
// Validate the AIN_6_7_DifferentialBipolarFSVref setting
#if AIN_6_7_DifferentialBipolarFSVref
# if AIN_6_7_DifferentialUnipolar
#  error("cannot have both AIN_6_7_DifferentialBipolarFSVref and AIN_6_7_DifferentialUnipolar; choose one")
# endif // AIN_6_7_DifferentialUnipolar
# if AIN_6_7_SingleEnded
#  error("cannot have both AIN_6_7_DifferentialBipolarFSVref and AIN_6_7_SingleEnded; choose one")
# endif // AIN_6_7_SingleEnded
#endif // AIN_6_7_DifferentialBipolarFSVref
//
// Validate the AIN_6_7_DifferentialUnipolar setting
#if AIN_6_7_DifferentialUnipolar
# if AIN_6_7_SingleEnded
#  error("cannot have both AIN_6_7_DifferentialUnipolar and AIN_6_7_SingleEnded; choose one")
# endif // AIN_6_7_SingleEnded
#endif // AIN_6_7_DifferentialUnipolar

//----------------------------------------
// ADC Channels AIN8, AIN9
//
// CUSTOMIZE: select one of the following options
// either by uncommenting in this file or define at the project level
//--------------------
// ADC Channels AIN8, AIN9 = Differential Bipolar
// Full Scale = 2 * VREF
// Voltage per LSB count = VREF/2048
// AIN8, AIN9 are a Differential pair using Bipolar transfer function with range (+/-)Vref
// AIN8 voltage must always be between 0 and VREF.
// AIN9 voltage must always be between 0 and VREF.
//
//~ #define AIN_8_9_DifferentialBipolarFS2Vref 	1
//
//--------------------
// ADC Channels AIN8, AIN9 = Differential Bipolar
// Full Scale = VREF
// Voltage per LSB count = VREF/2048
// AIN8, AIN9 are a Differential pair using Bipolar transfer function with range (+/-)(1/2)Vref
// AIN8 voltage must always be between 0 and VREF.
// AIN9 voltage must always be between 0 and VREF.
//
//~ #define AIN_8_9_DifferentialBipolarFSVref 	1
//
//--------------------
// ADC Channels AIN8, AIN9 = Differential Unipolar (AIN8 > AIN9)
// Full Scale = VREF
// Voltage per LSB count = VREF/2048
// AIN8, AIN9 are a Differential pair using Unipolar transfer function.
// AIN8 voltage must always be between 0 and VREF.
// AIN9 voltage must always be between 0 and VREF.
//
//~ #define AIN_8_9_DifferentialUnipolar 	1
//
//--------------------
// ADC Channels AIN8, AIN9 = Both Single-Ended, Unipolar
// Full Scale = VREF
// Voltage per LSB count = VREF/2048
// AIN8 is a Single-Ended input using Unipolar transfer function.
// AIN9 is a Single-Ended input using Unipolar transfer function.
// If PDIFF_COM_1, both are Pseudo-Differential with REF- as common.
// AIN8 voltage must always be between 0 and VREF.
// AIN9 voltage must always be between 0 and VREF.
//
//~ #define AIN_8_9_SingleEnded 	1
//
//--------------------
//
// Default settings if not defined at project level
#ifndef AIN_8_9_DifferentialBipolarFS2Vref
# ifndef AIN_8_9_DifferentialBipolarFSVref
#  ifndef AIN_8_9_DifferentialUnipolar
#   ifndef AIN_8_9_SingleEnded
#    define AIN_8_9_DifferentialBipolarFS2Vref 	0
#    define AIN_8_9_DifferentialBipolarFSVref 	0
#    define AIN_8_9_DifferentialUnipolar 	0
#    define AIN_8_9_SingleEnded 	1
#   endif // AIN_8_9_SingleEnded
#  endif // AIN_8_9_DifferentialUnipolar
# endif // AIN_8_9_DifferentialBipolarFSVref
#endif // AIN_8_9_DifferentialBipolarFS2Vref
//
// (optional diagnostic) pragma message the active setting
#if AIN_8_9_DifferentialBipolarFS2Vref
//~ #  pragma message("AIN_8_9_DifferentialBipolarFS2Vref: ADC Channels AIN8, AIN9 = Differential Bipolar")
#endif // AIN_8_9_DifferentialBipolarFS2Vref
#if AIN_8_9_DifferentialBipolarFSVref
//~ #  pragma message("AIN_8_9_DifferentialBipolarFSVref: ADC Channels AIN8, AIN9 = Differential Bipolar")
#endif // AIN_8_9_DifferentialBipolarFSVref
#if AIN_8_9_DifferentialUnipolar
//~ #  pragma message("AIN_8_9_DifferentialUnipolar: ADC Channels AIN8, AIN9 = Differential Unipolar (AIN8 > AIN9)")
#endif // AIN_8_9_DifferentialUnipolar
#if AIN_8_9_SingleEnded
//~ #  pragma message("AIN_8_9_SingleEnded: ADC Channels AIN8, AIN9 = Both Single-Ended, Unipolar")
#endif // AIN_8_9_SingleEnded
//
// Validate the AIN_8_9_DifferentialBipolarFS2Vref setting
#if AIN_8_9_DifferentialBipolarFS2Vref
# if AIN_8_9_DifferentialBipolarFSVref
#  error("cannot have both AIN_8_9_DifferentialBipolarFS2Vref and AIN_8_9_DifferentialBipolarFSVref; choose one")
# endif // AIN_8_9_DifferentialBipolarFSVref
# if AIN_8_9_DifferentialUnipolar
#  error("cannot have both AIN_8_9_DifferentialBipolarFS2Vref and AIN_8_9_DifferentialUnipolar; choose one")
# endif // AIN_8_9_DifferentialUnipolar
# if AIN_8_9_SingleEnded
#  error("cannot have both AIN_8_9_DifferentialBipolarFS2Vref and AIN_8_9_SingleEnded; choose one")
# endif // AIN_8_9_SingleEnded
#endif // AIN_8_9_DifferentialBipolarFS2Vref
//
// Validate the AIN_8_9_DifferentialBipolarFSVref setting
#if AIN_8_9_DifferentialBipolarFSVref
# if AIN_8_9_DifferentialUnipolar
#  error("cannot have both AIN_8_9_DifferentialBipolarFSVref and AIN_8_9_DifferentialUnipolar; choose one")
# endif // AIN_8_9_DifferentialUnipolar
# if AIN_8_9_SingleEnded
#  error("cannot have both AIN_8_9_DifferentialBipolarFSVref and AIN_8_9_SingleEnded; choose one")
# endif // AIN_8_9_SingleEnded
#endif // AIN_8_9_DifferentialBipolarFSVref
//
// Validate the AIN_8_9_DifferentialUnipolar setting
#if AIN_8_9_DifferentialUnipolar
# if AIN_8_9_SingleEnded
#  error("cannot have both AIN_8_9_DifferentialUnipolar and AIN_8_9_SingleEnded; choose one")
# endif // AIN_8_9_SingleEnded
#endif // AIN_8_9_DifferentialUnipolar

//----------------------------------------
// ADC Channels AIN10, AIN11
//
// CUSTOMIZE: select one of the following options
// either by uncommenting in this file or define at the project level
//--------------------
// ADC Channels AIN10, AIN11 = Differential Bipolar
// Full Scale = 2 * VREF
// Voltage per LSB count = VREF/2048
// AIN10, AIN11 are a Differential pair using Bipolar transfer function with range (+/-)Vref
// AIN10 voltage must always be between 0 and VREF.
// AIN11 voltage must always be between 0 and VREF.
//
//~ #define AIN_10_11_DifferentialBipolarFS2Vref 	1
//
//--------------------
// ADC Channels AIN10, AIN11 = Differential Bipolar
// Full Scale = VREF
// Voltage per LSB count = VREF/2048
// AIN10, AIN11 are a Differential pair using Bipolar transfer function with range (+/-)(1/2)Vref
// AIN10 voltage must always be between 0 and VREF.
// AIN11 voltage must always be between 0 and VREF.
//
//~ #define AIN_10_11_DifferentialBipolarFSVref 	1
//
//--------------------
// ADC Channels AIN10, AIN11 = Differential Unipolar (AIN10 > AIN11)
// Full Scale = VREF
// Voltage per LSB count = VREF/2048
// AIN10, AIN11 are a Differential pair using Unipolar transfer function.
// AIN10 voltage must always be between 0 and VREF.
// AIN11 voltage must always be between 0 and VREF.
//
//~ #define AIN_10_11_DifferentialUnipolar 	1
//
//--------------------
// ADC Channels AIN10, AIN11 = Both Single-Ended, Unipolar
// Full Scale = VREF
// Voltage per LSB count = VREF/2048
// AIN10 is a Single-Ended input using Unipolar transfer function.
// AIN11 is a Single-Ended input using Unipolar transfer function.
// If PDIFF_COM_1, both are Pseudo-Differential with REF- as common.
// AIN10 voltage must always be between 0 and VREF.
// AIN11 voltage must always be between 0 and VREF.
//
//~ #define AIN_10_11_SingleEnded 	1
//
//--------------------
//
// Default settings if not defined at project level
#ifndef AIN_10_11_DifferentialBipolarFS2Vref
# ifndef AIN_10_11_DifferentialBipolarFSVref
#  ifndef AIN_10_11_DifferentialUnipolar
#   ifndef AIN_10_11_SingleEnded
#    define AIN_10_11_DifferentialBipolarFS2Vref 	0
#    define AIN_10_11_DifferentialBipolarFSVref 	0
#    define AIN_10_11_DifferentialUnipolar 	0
#    define AIN_10_11_SingleEnded 	1
#   endif // AIN_10_11_SingleEnded
#  endif // AIN_10_11_DifferentialUnipolar
# endif // AIN_10_11_DifferentialBipolarFSVref
#endif // AIN_10_11_DifferentialBipolarFS2Vref
//
// (optional diagnostic) pragma message the active setting
#if AIN_10_11_DifferentialBipolarFS2Vref
//~ #  pragma message("AIN_10_11_DifferentialBipolarFS2Vref: ADC Channels AIN10, AIN11 = Differential Bipolar")
#endif // AIN_10_11_DifferentialBipolarFS2Vref
#if AIN_10_11_DifferentialBipolarFSVref
//~ #  pragma message("AIN_10_11_DifferentialBipolarFSVref: ADC Channels AIN10, AIN11 = Differential Bipolar")
#endif // AIN_10_11_DifferentialBipolarFSVref
#if AIN_10_11_DifferentialUnipolar
//~ #  pragma message("AIN_10_11_DifferentialUnipolar: ADC Channels AIN10, AIN11 = Differential Unipolar (AIN10 > AIN11)")
#endif // AIN_10_11_DifferentialUnipolar
#if AIN_10_11_SingleEnded
//~ #  pragma message("AIN_10_11_SingleEnded: ADC Channels AIN10, AIN11 = Both Single-Ended, Unipolar")
#endif // AIN_10_11_SingleEnded
//
// Validate the AIN_10_11_DifferentialBipolarFS2Vref setting
#if AIN_10_11_DifferentialBipolarFS2Vref
# if AIN_10_11_DifferentialBipolarFSVref
#  error("cannot have both AIN_10_11_DifferentialBipolarFS2Vref and AIN_10_11_DifferentialBipolarFSVref; choose one")
# endif // AIN_10_11_DifferentialBipolarFSVref
# if AIN_10_11_DifferentialUnipolar
#  error("cannot have both AIN_10_11_DifferentialBipolarFS2Vref and AIN_10_11_DifferentialUnipolar; choose one")
# endif // AIN_10_11_DifferentialUnipolar
# if AIN_10_11_SingleEnded
#  error("cannot have both AIN_10_11_DifferentialBipolarFS2Vref and AIN_10_11_SingleEnded; choose one")
# endif // AIN_10_11_SingleEnded
#endif // AIN_10_11_DifferentialBipolarFS2Vref
//
// Validate the AIN_10_11_DifferentialBipolarFSVref setting
#if AIN_10_11_DifferentialBipolarFSVref
# if AIN_10_11_DifferentialUnipolar
#  error("cannot have both AIN_10_11_DifferentialBipolarFSVref and AIN_10_11_DifferentialUnipolar; choose one")
# endif // AIN_10_11_DifferentialUnipolar
# if AIN_10_11_SingleEnded
#  error("cannot have both AIN_10_11_DifferentialBipolarFSVref and AIN_10_11_SingleEnded; choose one")
# endif // AIN_10_11_SingleEnded
#endif // AIN_10_11_DifferentialBipolarFSVref
//
// Validate the AIN_10_11_DifferentialUnipolar setting
#if AIN_10_11_DifferentialUnipolar
# if AIN_10_11_SingleEnded
#  error("cannot have both AIN_10_11_DifferentialUnipolar and AIN_10_11_SingleEnded; choose one")
# endif // AIN_10_11_SingleEnded
#endif // AIN_10_11_DifferentialUnipolar

//----------------------------------------
// ADC Channels AIN12, AIN13
//
// CUSTOMIZE: select one of the following options
// either by uncommenting in this file or define at the project level
//--------------------
// ADC Channels AIN12, AIN13 = Differential Bipolar
// Full Scale = 2 * VREF
// Voltage per LSB count = VREF/2048
// AIN12, AIN13 are a Differential pair using Bipolar transfer function with range (+/-)Vref
// AIN12 voltage must always be between 0 and VREF.
// AIN13 voltage must always be between 0 and VREF.
//
//~ #define AIN_12_13_DifferentialBipolarFS2Vref 	1
//
//--------------------
// ADC Channels AIN12, AIN13 = Differential Bipolar
// Full Scale = VREF
// Voltage per LSB count = VREF/2048
// AIN12, AIN13 are a Differential pair using Bipolar transfer function with range (+/-)(1/2)Vref
// AIN12 voltage must always be between 0 and VREF.
// AIN13 voltage must always be between 0 and VREF.
//
//~ #define AIN_12_13_DifferentialBipolarFSVref 	1
//
//--------------------
// ADC Channels AIN12, AIN13 = Differential Unipolar (AIN12 > AIN13)
// Full Scale = VREF
// Voltage per LSB count = VREF/2048
// AIN12, AIN13 are a Differential pair using Unipolar transfer function.
// AIN12 voltage must always be between 0 and VREF.
// AIN13 voltage must always be between 0 and VREF.
//
//~ #define AIN_12_13_DifferentialUnipolar 	1
//
//--------------------
// ADC Channels AIN12, AIN13 = Both Single-Ended, Unipolar
// Full Scale = VREF
// Voltage per LSB count = VREF/2048
// AIN12 is a Single-Ended input using Unipolar transfer function.
// AIN13 is a Single-Ended input using Unipolar transfer function.
// If PDIFF_COM_1, both are Pseudo-Differential with REF- as common.
// AIN12 voltage must always be between 0 and VREF.
// AIN13 voltage must always be between 0 and VREF.
//
//~ #define AIN_12_13_SingleEnded 	1
//
//--------------------
//
// Default settings if not defined at project level
#ifndef AIN_12_13_DifferentialBipolarFS2Vref
# ifndef AIN_12_13_DifferentialBipolarFSVref
#  ifndef AIN_12_13_DifferentialUnipolar
#   ifndef AIN_12_13_SingleEnded
#    define AIN_12_13_DifferentialBipolarFS2Vref 	0
#    define AIN_12_13_DifferentialBipolarFSVref 	0
#    define AIN_12_13_DifferentialUnipolar 	0
#    define AIN_12_13_SingleEnded 	1
#   endif // AIN_12_13_SingleEnded
#  endif // AIN_12_13_DifferentialUnipolar
# endif // AIN_12_13_DifferentialBipolarFSVref
#endif // AIN_12_13_DifferentialBipolarFS2Vref
//
// (optional diagnostic) pragma message the active setting
#if AIN_12_13_DifferentialBipolarFS2Vref
//~ #  pragma message("AIN_12_13_DifferentialBipolarFS2Vref: ADC Channels AIN12, AIN13 = Differential Bipolar")
#endif // AIN_12_13_DifferentialBipolarFS2Vref
#if AIN_12_13_DifferentialBipolarFSVref
//~ #  pragma message("AIN_12_13_DifferentialBipolarFSVref: ADC Channels AIN12, AIN13 = Differential Bipolar")
#endif // AIN_12_13_DifferentialBipolarFSVref
#if AIN_12_13_DifferentialUnipolar
//~ #  pragma message("AIN_12_13_DifferentialUnipolar: ADC Channels AIN12, AIN13 = Differential Unipolar (AIN12 > AIN13)")
#endif // AIN_12_13_DifferentialUnipolar
#if AIN_12_13_SingleEnded
//~ #  pragma message("AIN_12_13_SingleEnded: ADC Channels AIN12, AIN13 = Both Single-Ended, Unipolar")
#endif // AIN_12_13_SingleEnded
//
// Validate the AIN_12_13_DifferentialBipolarFS2Vref setting
#if AIN_12_13_DifferentialBipolarFS2Vref
# if AIN_12_13_DifferentialBipolarFSVref
#  error("cannot have both AIN_12_13_DifferentialBipolarFS2Vref and AIN_12_13_DifferentialBipolarFSVref; choose one")
# endif // AIN_12_13_DifferentialBipolarFSVref
# if AIN_12_13_DifferentialUnipolar
#  error("cannot have both AIN_12_13_DifferentialBipolarFS2Vref and AIN_12_13_DifferentialUnipolar; choose one")
# endif // AIN_12_13_DifferentialUnipolar
# if AIN_12_13_SingleEnded
#  error("cannot have both AIN_12_13_DifferentialBipolarFS2Vref and AIN_12_13_SingleEnded; choose one")
# endif // AIN_12_13_SingleEnded
#endif // AIN_12_13_DifferentialBipolarFS2Vref
//
// Validate the AIN_12_13_DifferentialBipolarFSVref setting
#if AIN_12_13_DifferentialBipolarFSVref
# if AIN_12_13_DifferentialUnipolar
#  error("cannot have both AIN_12_13_DifferentialBipolarFSVref and AIN_12_13_DifferentialUnipolar; choose one")
# endif // AIN_12_13_DifferentialUnipolar
# if AIN_12_13_SingleEnded
#  error("cannot have both AIN_12_13_DifferentialBipolarFSVref and AIN_12_13_SingleEnded; choose one")
# endif // AIN_12_13_SingleEnded
#endif // AIN_12_13_DifferentialBipolarFSVref
//
// Validate the AIN_12_13_DifferentialUnipolar setting
#if AIN_12_13_DifferentialUnipolar
# if AIN_12_13_SingleEnded
#  error("cannot have both AIN_12_13_DifferentialUnipolar and AIN_12_13_SingleEnded; choose one")
# endif // AIN_12_13_SingleEnded
#endif // AIN_12_13_DifferentialUnipolar

//----------------------------------------
// ADC Channels AIN14, AIN15
//
// CUSTOMIZE: select one of the following options
// either by uncommenting in this file or define at the project level
//--------------------
// ADC Channels AIN14, AIN15 = Differential Bipolar
// Full Scale = 2 * VREF
// Voltage per LSB count = VREF/2048
// AIN14, AIN15 are a Differential pair using Bipolar transfer function with range (+/-)Vref
// AIN14 voltage must always be between 0 and VREF.
// AIN15 voltage must always be between 0 and VREF.
//
//~ #define AIN_14_15_DifferentialBipolarFS2Vref 	1
//
//--------------------
// ADC Channels AIN14, AIN15 = Differential Bipolar
// Full Scale = VREF
// Voltage per LSB count = VREF/2048
// AIN14, AIN15 are a Differential pair using Bipolar transfer function with range (+/-)(1/2)Vref
// AIN14 voltage must always be between 0 and VREF.
// AIN15 voltage must always be between 0 and VREF.
//
//~ #define AIN_14_15_DifferentialBipolarFSVref 	1
//
//--------------------
// ADC Channels AIN14, AIN15 = Differential Unipolar (AIN14 > AIN15)
// Full Scale = VREF
// Voltage per LSB count = VREF/2048
// AIN14, AIN15 are a Differential pair using Unipolar transfer function.
// AIN14 voltage must always be between 0 and VREF.
// AIN15 voltage must always be between 0 and VREF.
//
//~ #define AIN_14_15_DifferentialUnipolar 	1
//
//--------------------
// ADC Channels AIN14, AIN15 = Both Single-Ended, Unipolar
// Full Scale = VREF
// Voltage per LSB count = VREF/2048
// AIN14 is a Single-Ended input using Unipolar transfer function.
// AIN15 is a Single-Ended input using Unipolar transfer function.
// If PDIFF_COM_1, both are Pseudo-Differential with REF- as common.
// AIN14 voltage must always be between 0 and VREF.
// AIN15 voltage must always be between 0 and VREF.
//
//~ #define AIN_14_15_SingleEnded 	1
//
//--------------------
//
// Default settings if not defined at project level
#ifndef AIN_14_15_DifferentialBipolarFS2Vref
# ifndef AIN_14_15_DifferentialBipolarFSVref
#  ifndef AIN_14_15_DifferentialUnipolar
#   ifndef AIN_14_15_SingleEnded
#    define AIN_14_15_DifferentialBipolarFS2Vref 	0
#    define AIN_14_15_DifferentialBipolarFSVref 	0
#    define AIN_14_15_DifferentialUnipolar 	0
#    define AIN_14_15_SingleEnded 	1
#   endif // AIN_14_15_SingleEnded
#  endif // AIN_14_15_DifferentialUnipolar
# endif // AIN_14_15_DifferentialBipolarFSVref
#endif // AIN_14_15_DifferentialBipolarFS2Vref
//
// (optional diagnostic) pragma message the active setting
#if AIN_14_15_DifferentialBipolarFS2Vref
//~ #  pragma message("AIN_14_15_DifferentialBipolarFS2Vref: ADC Channels AIN14, AIN15 = Differential Bipolar")
#endif // AIN_14_15_DifferentialBipolarFS2Vref
#if AIN_14_15_DifferentialBipolarFSVref
//~ #  pragma message("AIN_14_15_DifferentialBipolarFSVref: ADC Channels AIN14, AIN15 = Differential Bipolar")
#endif // AIN_14_15_DifferentialBipolarFSVref
#if AIN_14_15_DifferentialUnipolar
//~ #  pragma message("AIN_14_15_DifferentialUnipolar: ADC Channels AIN14, AIN15 = Differential Unipolar (AIN14 > AIN15)")
#endif // AIN_14_15_DifferentialUnipolar
#if AIN_14_15_SingleEnded
//~ #  pragma message("AIN_14_15_SingleEnded: ADC Channels AIN14, AIN15 = Both Single-Ended, Unipolar")
#endif // AIN_14_15_SingleEnded
//
// Validate the AIN_14_15_DifferentialBipolarFS2Vref setting
#if AIN_14_15_DifferentialBipolarFS2Vref
# if AIN_14_15_DifferentialBipolarFSVref
#  error("cannot have both AIN_14_15_DifferentialBipolarFS2Vref and AIN_14_15_DifferentialBipolarFSVref; choose one")
# endif // AIN_14_15_DifferentialBipolarFSVref
# if AIN_14_15_DifferentialUnipolar
#  error("cannot have both AIN_14_15_DifferentialBipolarFS2Vref and AIN_14_15_DifferentialUnipolar; choose one")
# endif // AIN_14_15_DifferentialUnipolar
# if AIN_14_15_SingleEnded
#  error("cannot have both AIN_14_15_DifferentialBipolarFS2Vref and AIN_14_15_SingleEnded; choose one")
# endif // AIN_14_15_SingleEnded
#endif // AIN_14_15_DifferentialBipolarFS2Vref
//
// Validate the AIN_14_15_DifferentialBipolarFSVref setting
#if AIN_14_15_DifferentialBipolarFSVref
# if AIN_14_15_DifferentialUnipolar
#  error("cannot have both AIN_14_15_DifferentialBipolarFSVref and AIN_14_15_DifferentialUnipolar; choose one")
# endif // AIN_14_15_DifferentialUnipolar
# if AIN_14_15_SingleEnded
#  error("cannot have both AIN_14_15_DifferentialBipolarFSVref and AIN_14_15_SingleEnded; choose one")
# endif // AIN_14_15_SingleEnded
#endif // AIN_14_15_DifferentialBipolarFSVref
//
// Validate the AIN_14_15_DifferentialUnipolar setting
#if AIN_14_15_DifferentialUnipolar
# if AIN_14_15_SingleEnded
#  error("cannot have both AIN_14_15_DifferentialUnipolar and AIN_14_15_SingleEnded; choose one")
# endif // AIN_14_15_SingleEnded
#endif // AIN_14_15_DifferentialUnipolar

/**
 * @brief MAX11131 3Msps, Low-Power, Serial SPI 12-Bit, 16-Channel, Differential/Single-Ended Input, SAR ADC
 *
 *
 *
 * Datasheet: https://www.maximintegrated.com/MAX11131
 *
 *
 *
 * @code
 * // example code includes
 * // standard include for target platform -- Platform_Include_Boilerplate
 * #include "mbed.h"
 * // Platforms:
 * //   - MAX32625MBED
 * //      - supports mbed-os-5.11, requires USBDevice library
 * //      - add https://developer.mbed.org/teams/MaximIntegrated/code/USBDevice/
 * //      - remove max32630fthr library (if present)
 * //      - remove MAX32620FTHR library (if present)
 * //   - MAX32600MBED
 * //      - Please note the last supported version is Mbed OS 6.3.
 * //      - remove max32630fthr library (if present)
 * //      - remove MAX32620FTHR library (if present)
 * //      - Windows 10 note:  Don't connect HDK until you are ready to load new firmware into the board.
 * //   - NUCLEO_F446RE
 * //      - remove USBDevice library
 * //      - remove max32630fthr library (if present)
 * //      - remove MAX32620FTHR library (if present)
 * //   - NUCLEO_F401RE
 * //      - remove USBDevice library
 * //      - remove max32630fthr library (if present)
 * //      - remove MAX32620FTHR library (if present)
 * //   - MAX32630FTHR
 * //      - #include "max32630fthr.h"
 * //      - add http://developer.mbed.org/teams/MaximIntegrated/code/max32630fthr/
 * //      - remove MAX32620FTHR library (if present)
 * //   - MAX32620FTHR
 * //      - #include "MAX32620FTHR.h"
 * //      - remove max32630fthr library (if present)
 * //      - add https://os.mbed.com/teams/MaximIntegrated/code/MAX32620FTHR/
 * //      - not tested yet
 * //   - MAX32625PICO
 * //      - #include "max32625pico.h"
 * //      - add https://os.mbed.com/users/switches/code/max32625pico/
 * //      - remove max32630fthr library (if present)
 * //      - remove MAX32620FTHR library (if present)
 * //      - not tested yet
 * //      - see https://os.mbed.com/users/switches/code/max32625pico/
 * //      - see https://os.mbed.com/users/switches/code/PICO_board_demo/
 * //      - see https://os.mbed.com/users/switches/code/PICO_USB_I2C_SPI/
 * //      - see https://os.mbed.com/users/switches/code/SerialInterface/
 * //      - Note: To load the MAX32625PICO firmware, hold the button while
 * //        connecting the USB cable, then copy firmware bin file
 * //        to the MAINTENANCE drive.
 * //      - see https://os.mbed.com/platforms/MAX32625PICO/
 * //      - see https://os.mbed.com/teams/MaximIntegrated/wiki/MAX32625PICO-Firmware-Updates
 * //
 * // end Platform_Include_Boilerplate
 * #include "MAX11131.h"
 *
 * // example code board support
 * //MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3);
 * //DigitalOut rLED(LED1);
 * //DigitalOut gLED(LED2);
 * //DigitalOut bLED(LED3);
 * //
 * // Arduino "shield" connector port definitions (MAX32625MBED shown)
 * #if defined(TARGET_MAX32625MBED)
 * #define A0 AIN_0
 * #define A1 AIN_1
 * #define A2 AIN_2
 * #define A3 AIN_3
 * #define D0 P0_0
 * #define D1 P0_1
 * #define D2 P0_2
 * #define D3 P0_3
 * #define D4 P0_4
 * #define D5 P0_5
 * #define D6 P0_6
 * #define D7 P0_7
 * #define D8 P1_4
 * #define D9 P1_5
 * #define D10 P1_3
 * #define D11 P1_1
 * #define D12 P1_2
 * #define D13 P1_0
 * #elif defined(TARGET_MAX32625PICO)
 * #warning "TARGET_MAX32625PICO not previously tested; need to define pins..."
 * #define A0 AIN_1
 * #define A1 AIN_2
 * // #define A2 AIN_3
 * // #define A3 AIN_0
 * #define D0 P0_0
 * #define D1 P0_1
 * #define D2 P0_2
 * #define D3 P0_3
 * #define D4 P1_7
 * #define D5 P1_6
 * #define D6 P4_4
 * #define D7 P4_5
 * #define D8 P4_6
 * #define D9 P4_7
 * #define D10 P0_7
 * #define D11 P0_6
 * #define D12 P0_5
 * #define D13 P0_4
 * #endif
 *
 * // example code declare SPI interface (GPIO controlled CS)
 * #if defined(TARGET_MAX32625MBED)
 * SPI spi(SPI1_MOSI, SPI1_MISO, SPI1_SCK); // mosi, miso, sclk spi1 TARGET_MAX32625MBED: P1_1 P1_2 P1_0 Arduino 10-pin header D11 D12 D13
 * DigitalOut spi_cs(SPI1_SS); // TARGET_MAX32625MBED: P1_3 Arduino 10-pin header D10
 * #elif defined(TARGET_MAX32625PICO)
 * #warning "TARGET_MAX32625PICO not previously tested; need to define pins..."
 * SPI spi(SPI0_MOSI, SPI0_MISO, SPI0_SCK); // mosi, miso, sclk spi1 TARGET_MAX32625PICO: pin P0_5 P0_6 P0_4
 * DigitalOut spi_cs(SPI0_SS); // TARGET_MAX32625PICO: pin P0_7
 * #elif defined(TARGET_MAX32600MBED)
 * SPI spi(SPI2_MOSI, SPI2_MISO, SPI2_SCK); // mosi, miso, sclk spi1 TARGET_MAX32600MBED: Arduino 10-pin header D11 D12 D13
 * DigitalOut spi_cs(SPI2_SS); // Generic: Arduino 10-pin header D10
 * #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
 * //
 * #else
 * SPI spi(D11, D12, D13); // mosi, miso, sclk spi1 TARGET_MAX32600MBED: Arduino 10-pin header D11 D12 D13
 * DigitalOut spi_cs(D10); // Generic: Arduino 10-pin header D10
 * #endif
 *
 * // example code declare GPIO interface pins
 * DigitalOut CNVST_pin(D9); // Digital Trigger Input to MAX11131 device
 * // AnalogOut REF_plus_pin(Px_x_PortName_To_Be_Determined); // Reference Input to MAX11131 device
 * // AnalogOut REF_minus_slash_AIN15_pin(Px_x_PortName_To_Be_Determined); // Reference Input to MAX11131 device
 * DigitalIn EOC_pin(D2); // Digital Event Output from MAX11131 device
 * // example code declare device instance
 * MAX11131 g_MAX11131_device(spi, spi_cs, CNVST_pin, EOC_pin, MAX11131::MAX11131_IC);
 *
 * //--------------------------------------------------
 * // 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 serial;
 * //--------------------------------------------------
 * #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 serial;
 * //--------------------------------------------------
 * #elif defined(TARGET_MAX32600)
 *     #include "USBSerial.h"
 * // Hardware serial port over DAPLink
 * // The default baud rate for the DapLink UART is 9600
 * Serial DAPLINKserial(P1_1, P1_0);     // tx, rx
 *     #define HAS_DAPLINK_SERIAL 1
 * // Virtual serial port over USB
 * // The baud rate does not affect the virtual USBSerial UART.
 * USBSerial serial;
 * //--------------------------------------------------
 * #elif defined(TARGET_NUCLEO_F446RE) || defined(TARGET_NUCLEO_F401RE)
 * Serial serial(SERIAL_TX, SERIAL_RX);     // tx, rx
 * //--------------------------------------------------
 * #else
 * #if defined(SERIAL_TX)
 * #warning "target not previously tested; guess serial pins are SERIAL_TX, SERIAL_RX..."
 * Serial serial(SERIAL_TX, SERIAL_RX);     // tx, rx
 * #elif defined(USBTX)
 * #warning "target not previously tested; guess serial pins are USBTX, USBRX..."
 * Serial serial(USBTX, USBRX);     // tx, rx
 * #elif defined(UART_TX)
 * #warning "target not previously tested; guess serial pins are UART_TX, UART_RX..."
 * Serial serial(UART_TX, UART_RX);     // tx, rx
 * #else
 * #warning "target not previously tested; need to define serial pins..."
 * #endif
 * #endif
 * //
 * #include "CmdLine.h"
 * CmdLine cmdLine(serial, "serial");
 *
 * // example code main function
 * int main()
 * {
 *     // setup: put your setup code here, to run once
 *
 *     g_MAX11131_device.Init();
 *
 *     while (1)
 *     {
 *         // loop: put your main code here, to run repeatedly
 *
 *         // banner for csv data columns
 *         while(1) { // this code repeats forever
 *             // this code repeats forever
 *             // Measure ADC channels in sequence from AIN0 to channelNumber_0_15.
 *             // @param[in] g_MAX11131_device.channelNumber_0_15: AIN Channel Number
 *             // @param[in] g_MAX11131_device.PowerManagement_0_2: 0=Normal, 1=AutoShutdown, 2=AutoStandby
 *             // @param[in] g_MAX11131_device.chan_id_0_1: ADC_MODE_CONTROL.CHAN_ID
 *             int channelId_0_15 = 15;
 *             g_MAX11131_device.channelNumber_0_15 = channelId_0_15;
 *             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
 *
 *             // wait(3.0);
 *             // Use Arduino Serial Plotter to view output: Tools | Serial Plotter
 *             cmdLine.serial().printf("%d", g_MAX11131_device.AINcode[0]);
 *             for (int index = 1; index <= channelId_0_15; index++) {
 *                 cmdLine.serial().printf(",%d", g_MAX11131_device.AINcode[index]);
 *             }
 *             cmdLine.serial().printf("\r\n");
 *
 *         } // this code repeats forever
 *     }
 * }
 * @endcode
 */
class MAX11131 {
public:
    //----------------------------------------
    /// ADC_MODE_CONTROL.SCAN[3:0] ADC Scan Control (command)
    typedef enum MAX11131_SCAN_enum_t {
        SCAN_0000_NOP = 0x00, //!< 0b0000
        SCAN_0001_Manual = 0x01, //!< 0b0001
        SCAN_0010_Repeat = 0x02, //!< 0b0010
        SCAN_0011_StandardInternalClock = 0x03, //!< 0b0011
        SCAN_0100_StandardExternalClock = 0x04, //!< 0b0100
        SCAN_0101_UpperInternalClock = 0x05, //!< 0b0101
        SCAN_0110_UpperExternalClock = 0x06, //!< 0b0110
        SCAN_0111_CustomInternalClock = 0x07, //!< 0b0111
        SCAN_1000_CustomExternalClock = 0x08, //!< 0b1000
        SCAN_1001_SampleSetExternalClock = 0x09, //!< 0b1001
    } MAX11131_SCAN_enum_t;

    //----------------------------------------
    /// ADC_MODE_CONTROL.RESET[1:0] Reset 0=Normal 1=ResetFIFO 2=ResetAllRegisters 3=reserved
    typedef enum MAX11131_RESET_enum_t {
        RESET_00_Normal = 0x00, //!< 0b00
        RESET_01_ResetFIFO = 0x01, //!< 0b01
        RESET_10_ResetAllRegisters = 0x02, //!< 0b10
    } MAX11131_RESET_enum_t;

    //----------------------------------------
    /// ADC_MODE_CONTROL.PM[1:0] Power Management 0=Normal, 1=AutoShutdown, 2=AutoStandby 3=reserved
    typedef enum MAX11131_PM_enum_t {
        PM_00_Normal = 0x00, //!< 0b00
        PM_01_AutoShutdown = 0x01, //!< 0b01
        PM_10_AutoStandby = 0x02, //!< 0b10
    } MAX11131_PM_enum_t;

    /**
     * @brief IC's supported with this driver
     * @details MAX11131
     */
    typedef enum
    {
        MAX11131_IC = 0,
        //MAX11131_IC = 1
    } MAX11131_ic_t;

    /**********************************************************//**
    * @brief Constructor for MAX11131 Class.
    *
    * @details Requires an existing SPI object as well as a DigitalOut object.
    * The DigitalOut object is used for a chip enable signal
    *
    * On Entry:
    *     @param[in] spi - pointer to existing SPI object
    *     @param[in] cs_pin - pointer to a DigitalOut pin object
    *     @param[in] CNVST_pin - pointer to a DigitalOut pin object
    *     @param[in] EOC_pin - pointer to a DigitalIn pin object
    *     @param[in] ic_variant - which type of MAX11131 is used
    *
    * On Exit:
    *
    * @return None
    **************************************************************/
    MAX11131(SPI &spi, DigitalOut &cs_pin, // SPI interface
            DigitalOut &CNVST_pin, // Digital Trigger Input to MAX11131 device
            // AnalogOut &REF_plus_pin, // Reference Input to MAX11131 device
            // AnalogOut &REF_minus_slash_AIN15_pin, // Reference Input to MAX11131 device
            DigitalIn &EOC_pin, // Digital Event Output from MAX11131 device
            MAX11131_ic_t ic_variant);

    /************************************************************
     * @brief Default destructor for MAX11131 Class.
     *
     * @details Destroys SPI object if owner
     *
     * On Entry:
     *
     * On Exit:
     *
     * @return None
     **************************************************************/
    ~MAX11131();

    /// Function pointer void f(size_t byteCount, uint8_t mosiData[], uint8_t misoData[])
    Callback<void(size_t, uint8_t*, uint8_t*)> onSPIprint; //!< optional @ref onSPIprint SPI diagnostic function

    /// set SPI SCLK frequency
    void spi_frequency(int spi_sclk_Hz);

    /// get SPI SCLK frequency
    int get_spi_frequency() const { return m_SPI_SCLK_Hz; }

    /// get SPI mode
    int get_spi_dataMode() const { return m_SPI_dataMode; }

//----------------------------------------
public:

    /// shadow of write-only register ADC_MODE_CONTROL
    /// mosiData16 0x0000..0x7FFF format: 0 SCAN[3:0] CHSEL[3:0] RESET[1:0] PM[1:0] CHAN_ID SWCNV 0
    int16_t ADC_MODE_CONTROL;

    /// shadow of write-only register ADC_CONFIGURATION
    /// mosiData16 0x8000..0x87FF format: 1 0 0 0 0 REFSEL AVGON NAVG[1:0] NSCAN[1:0] SPM[1:0] ECHO 0 0
    int16_t ADC_CONFIGURATION;

    /// shadow of write-only register UNIPOLAR
    /// mosiData16 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
    int16_t UNIPOLAR;

    /// shadow of write-only register BIPOLAR
    /// mosiData16 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
    int16_t BIPOLAR;

    /// shadow of write-only register RANGE
    /// mosiData16 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
    int16_t RANGE;

    /// shadow of write-only register CSCAN0
    /// mosiData16 0xA000..0xA7FF format: 1 0 1 0 0 CHSCAN15 CHSCAN14 CHSCAN13 CHSCAN12 CHSCAN11 CHSCAN10 CHSCAN9 CHSCAN8 x x x
    int16_t CSCAN0;

    /// shadow of write-only register CSCAN1
    /// mosiData16 0xA800..0xAFFF format: 1 0 1 0 1 CHSCAN7 CHSCAN6 CHSCAN5 CHSCAN4 CHSCAN3 CHSCAN2 CHSCAN1 CHSCAN0 x x x
    int16_t CSCAN1;

    /// shadow of write-only register SAMPLESET
    /// mosiData16 0xB000..0xB7FF format: 1 0 1 1 0 SEQ_LENGTH[7:0] x x x followed by enabledChannelsPattern.
    /// NOTE: Send the sampleset pattern, with 4 entries packed into each 16-bit SPI word. Pad unused entries with 0.
    /// NOTE: Keep CS low during the entire enabledChannelsPattern entry.
    int16_t SAMPLESET;

    /// unpacked SAMPLESET.SEQ_LENGTH[7:0] determines length of pattern
    /// NOTE: SAMPLESET.SEQ_LENGTH[7:0] is the number of channel entries in the pattern.
    /// NOTE: Each channel entry is 4 bits. The first 4 bits are the first channel in the sequence.
    /// NOTE: Channels can be repeated in any arbitrary order.
    /// NOTE: The channel entry pattern is sent immediately after writing SAMPLESET.
    uint8_t enabledChannelsPatternLength_1_256;

    /// unpacked shadow of write-only register SAMPLESET enabledChannelsPattern.
    /// Array Length = enabledChannelsPatternLength_1_256.
    /// Each entry is a channel number between 0 and 15.
    uint8_t enabledChannelsPattern[256];

    /// Diagnostic: what is the meaning of SPI Master Out data.
    /// 0:Nothing 1:regWrite 2:sampleSetPattern
    uint8_t SPI_MOSI_Semantic;

    /// number of ScanRead() words needed to retrieve all measurements.
    uint16_t NumWords;

    /// Is the currently configured mode external or internal clock. 1:External Clock 0:Internal Clock
    uint8_t isExternalClock;

    /// unpacked ADC_MODE_CONTROL.SCAN[3:0] Scan Mode MAX11131_SCAN_enum_t
    uint8_t ScanMode;

    /// unpacked ADC_MODE_CONTROL.CHSEL[3:0] Analog Input Channel Select
    uint8_t channelNumber_0_15;

    /// unpacked ADC_MODE_CONTROL.PM[1:0] Power Management MAX11131_PM_enum_t
    uint8_t PowerManagement_0_2;

    /// unpacked ADC_MODE_CONTROL.CHAN_ID
    uint8_t chan_id_0_1;

    /// unpacked ADC_CONFIGURATION.AVG and ADC_CONFIGURATION.NAVG[1:0] may be 0, 4, 8, 16, or 32
    uint8_t average_0_4_8_16_32;

    /// unpacked ADC_CONFIGURATION.NSCAN[1:0] may be 4, 8, 12, or 16
    uint8_t nscan_4_8_12_16;

    /// unpacked ADC_MODE_CONTROL.SWCNV
    uint8_t swcnv_0_1;

    /// unpacked CSCAN0 and CSCAN1
    int16_t enabledChannelsMask;

    /// Each channel's most recent value in LSBs.
    /// Updated by ReadAINcode function.
    /// Use VoltageOfCode function to convert LSBs to physical voltage.
    uint16_t AINcode[16];

    /// SPI master-in slave-out data.
    /// Updated by ReadAINcode function.
    /// SampleSet mode allows up to 256 channel entry selections.
    int16_t RAW_misoData16[256];

    /// reference voltage, in Volts
    double VRef;


//----------------------------------------
// set SPI SCLK frequency for MAX11131
//
    void SPIfrequency(int spi_sclk_Hz);

//----------------------------------------
// get SPI SCLK frequency for MAX11131
//
    int SPIgetFrequency();

//----------------------------------------
// Assert SPI Chip Select
// SPI chip-select for MAX11131
//
    void SPIoutputCS(int isLogicHigh);

//----------------------------------------
// SPI write 16 bits
// SPI interface to MAX11131 shift 16 bits mosiData16 into MAX11131 DIN
// ignoring MAX11131 DOUT
//
    void SPIwrite16bits(int16_t mosiData16);

//----------------------------------------
// 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);

//----------------------------------------
// SPI read 16 bits while MOSI (MAX11131 DIN) is 0
// SPI interface to capture 16 bits miso data from MAX11131 DOUT
//
    int16_t SPIread16bits();

//----------------------------------------
// Assert MAX11131 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();

//----------------------------------------
// Wait for MAX11131 EOC pin low, indicating end of conversion.
// Required when using any of the InternalClock modes.
//
    void EOCinputWaitUntilLow();

//----------------------------------------
// Return the status of the MAX11131 EOC pin.
//
    int EOCinputValue();

private:
    // SPI object
    SPI &m_spi;
    int m_SPI_SCLK_Hz;
    int m_SPI_dataMode;
    int m_SPI_cs_state;

    // Selector pin object
    DigitalOut &m_cs_pin;

// InputPin Name = CNVST
// InputPin Description = Active-Low Conversion Start Input/Analog Input 14
// InputPin Function = Trigger
    DigitalOut &m_CNVST_pin;
//
// InputPin Name = REF+
// InputPin Description = External Positive Reference Input. Apply a reference voltage at REF+. Bypass to GND with a 0.47uF capacitor.
// InputPin Function = Reference
    // AnalogOut &m_REF_plus_pin;
//
// InputPin Name = REF-/AIN15
// InputPin Description = External Differential Reference Negative Input/Analog Input 15
// InputPin Function = Reference
    // AnalogOut &m_REF_minus_slash_AIN15_pin;
//
// OutputPin Name = EOC
// OutputPin Description = End of Conversion Output. Data is valid after EOC pulls low (Internal clock mode only).
// OutputPin Function = Event
    DigitalIn &m_EOC_pin;
//

    // Identifies which IC variant is being used
    MAX11131_ic_t m_ic_variant;

public:

    //----------------------------------------
    /// Menu item '!'
    /// Initialize device
    ///
    /// TODO1: #170 MAX11131 Self Test for Test Fixture Firmware
    /// @future test group ____ // Verify function ____ (enabled by default)
    ///
    /// @future test group DACCodeOfVoltage // Verify function DACCodeOfVoltage (enabled by default)
    /// @future test group DACCodeOfVoltage tinyTester.blink_time_msec = 20 // quickly speed through the software verification
    /// @future test group DACCodeOfVoltage tinyTester.print("VRef = 2.500  MAX5171 14-bit LSB = 0.00015V")
    /// @future test group DACCodeOfVoltage VRef = 2.500
    /// @future test group DACCodeOfVoltage tinyTester.err_threshold = 0.00015259720441921504 // 14-bit LSB (2.500/16383)
    ///     //
    /// @future test group DACCodeOfVoltage DACCodeOfVoltage(2.499847412109375) expect 0x3FFF
    ///     //
    ///     //
    /// @future test group CODE_LOAD // Verify function CODE_LOAD (enabled by default)
    /// @future test group CODE_LOAD tinyTester.blink_time_msec = 75 // default 75 resume hardware self test
    /// @future test group CODE_LOAD tinyTester.settle_time_msec = 250
    /// @future test Init()
    /// @future test VRef expect 2.500 // Nominal Full-Scale Voltage Reference
    ///     //
    ///     tinyTester.err_threshold = 0.030; // 30mV
    /// @future test group CODE_LOAD tinyTester.err_threshold = 0.030
    /// @future test group CODE_LOAD tinyTester.DigitalIn_Read_Expect_WarnOnly(UPO_pin, "UPO", 1, "UPO_pin is high after MAX5171 UPO_HIGH command")
    /// @future test group CODE_LOAD tinyTester.AnalogIn0_Read_Expect_voltageV(1.2500)
    ///
    ///
    ///
    /// TODO1: #170 MAX11131 Self Test for Test Fixture Firmware
    /// @future test group ____ // Verify function ____ (enabled by default)
    /// @future test group ____ // Verify function ____ (enabled by default)
    ///     // 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("
    ///       0.0: MAX11131.Init()");
    ///     //g_MAX11131_device.Init();
    ///     //
    ///     // Device Testing: ADC commands, verify with on-board ADC and SPI framing
    ///     //
    /// @test group SPI48_3MSps // support 3MSps parts SCLK<=48MHz (enabled by default)
    /// @test group SPI48_3MSps tinyTester.print("SPI 48MHz")
    /// @test group SPI48_3MSps SPIfrequency(48000000); // support 3MSps parts SCLK<=48MHz
    /// @test group SPI48_3MSps SPIgetFrequency() expect 48000000
    /// @test group SPI48_3MSps tinyTester.settle_time_msec = 250 // default 250
    /// @test group SPI48_3MSps tinyTester.Wait_Output_Settling()
    /// @test group SPI48_3MSps SPIoutputCS(0)
    /// @test group SPI48_3MSps SPIread16bits()
    /// @test group SPI48_3MSps SPIoutputCS(1)
    /// //
    /// @test group SPI16MHz_1MSps // support 1MSps parts SCLK<=16MHz (enabled by default)
    /// @test group SPI16MHz_1MSps tinyTester.print("SPI 16MHz")
    /// @test group SPI16MHz_1MSps SPIfrequency(16000000); // support 1MSps parts SCLK<=16MHz
    /// @test group SPI16MHz_1MSps SPIgetFrequency() expect 16000000
    /// @test group SPI16MHz_1MSps tinyTester.settle_time_msec = 250 // default 250
    /// @test group SPI16MHz_1MSps tinyTester.Wait_Output_Settling()
    /// @test group SPI16MHz_1MSps SPIoutputCS(0)
    /// @test group SPI16MHz_1MSps SPIread16bits()
    /// @test group SPI16MHz_1MSps SPIoutputCS(1)
    /// //
    /// @test group SPI8MHz_500kSps // support 500kSps parts SCLK<=8MHz (enabled by default)
    /// @test group SPI8MHz_500kSps tinyTester.print("SPI 8MHz")
    /// @test group SPI8MHz_500kSps SPIfrequency(8000000); // support 500kSps parts SCLK<=8MHz
    /// @test group SPI8MHz_500kSps SPIgetFrequency() expect 8000000
    /// @test group SPI8MHz_500kSps tinyTester.settle_time_msec = 250 // default 250
    /// @test group SPI8MHz_500kSps tinyTester.Wait_Output_Settling()
    /// @test group SPI8MHz_500kSps SPIoutputCS(0)
    /// @test group SPI8MHz_500kSps SPIread16bits()
    /// @test group SPI8MHz_500kSps SPIoutputCS(1)
    /// //
    /// @test group SPI12MHz_1MSps // support 1MSps parts SCLK<=16MHz (enabled by default)
    /// @test group SPI12MHz_1MSps tinyTester.print("SPI 12MHz")
    /// @test group SPI12MHz_1MSps SPIfrequency(12000000); // support 1MSps parts SCLK<=16MHz
    /// @test group SPI12MHz_1MSps SPIgetFrequency() expect 12000000
    /// @test group SPI12MHz_1MSps tinyTester.settle_time_msec = 250 // default 250
    /// @test group SPI12MHz_1MSps tinyTester.Wait_Output_Settling()
    /// @test group SPI12MHz_1MSps SPIoutputCS(0)
    /// @test group SPI12MHz_1MSps SPIread16bits()
    /// @test group SPI12MHz_1MSps SPIoutputCS(1)
    /// //
    /// @test tinyTester.blink_time_msec = 75 // default 75 resume hardware self test
    ///     tinyTester.blink_time_msec = 75;
    ///     // MAX11131 SelfTest: MAX11131 SPI connections (Power Supply and GND, SCLK, MOSI, MISO, CS)
    ///     cmdLine.serial().printf("
    /// ");
    ///     cmdLine.serial().printf(
    ///         "
    ///       1.0: Test Scan_0100_StandardExt -- verify SPI (VDD, GND, SCLK, MOSI, MISO, CS)");
    /// @test tinyTester.print("0.0: MAX11131.Init()")
    ///     cmdLine.serial().printf("
    ///       MAX11131.Init()");
    ///     g_MAX11131_device.Init();
    /// @test Init()
    /// @test VRef expect 2.500 // Nominal Full-Scale Voltage Reference
    ///     //
    /// @test group TEST10_SCAN_0100 // Test SCAN_0100_StandardExt -- verify VDD,GND,SCLK,MOSI,MISO,CS (enabled by default)
    /// @test group TEST10_SCAN_0100 tinyTester.print("1.0: Test SCAN_0100_StandardExt -- verify VDD,GND,SCLK,MOSI,MISO,CS")
    /// @test group TEST10_SCAN_0100 SPIoutputCS(0)
    /// @test group TEST10_SCAN_0100 tinyTester.print("0000_0000_0100_0010  ADC_MODE_CONTROL SCAN_0000")
    /// @test group TEST10_SCAN_0100 tinyTester.print("                                      CHSEL=0 RESET=2 CHANID=1")
    /// @test group TEST10_SCAN_0100 SPIwrite16bits(0x0040)
    /// @test group TEST10_SCAN_0100 SPIoutputCS(1)
    /// @test group TEST10_SCAN_0100 SPIoutputCS(0)
    /// @test group TEST10_SCAN_0100 SPIread16bits()
    /// @test group TEST10_SCAN_0100 SPIoutputCS(1)
    /// @test group TEST10_SCAN_0100 SPIoutputCS(0)
    /// @test group TEST10_SCAN_0100 SPIread16bits()
    /// @test group TEST10_SCAN_0100 SPIoutputCS(1)
    /// @test group TEST10_SCAN_0100 SPIoutputCS(0)
    /// @test group TEST10_SCAN_0100 SPIread16bits()
    /// @test group TEST10_SCAN_0100 SPIoutputCS(1)
    /// @test group TEST10_SCAN_0100 tinyTester.print("1000_0000_0000_0000  ADC_CONFIGURATION REFSEL=0 SPM[1:0]=0 ECHO=0")
    /// @test group TEST10_SCAN_0100 SPIoutputCS(0)
    /// @test group TEST10_SCAN_0100 SPIwrite16bits(0x8000)
    /// @test group TEST10_SCAN_0100 SPIoutputCS(1)
    /// @test group TEST10_SCAN_0100 tinyTester.print("0010_0111_1010_0100  ADC_MODE_CONTROL SCAN_0100_StandardExt")
    /// @test group TEST10_SCAN_0100 tinyTester.print("                                      CHSEL=15 RESET=1 CHANID=1")
    /// @test group TEST10_SCAN_0100 SPIoutputCS(0)
    /// @test group TEST10_SCAN_0100 SPIwrite16bits(0x27a4)
    /// @test group TEST10_SCAN_0100 SPIoutputCS(1)
    /// @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0x0xxx (channel ID 0)")
    /// @test group TEST10_SCAN_0100 SPIoutputCS(0)
    /// @test group TEST10_SCAN_0100 SPIread16bits() expect 0x0000 mask 0xF000 // expect 0x0xxx (channel ID 0)
    /// @test group TEST10_SCAN_0100 SPIoutputCS(1)
    /// @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0x1xxx (channel ID 1)")
    /// @test group TEST10_SCAN_0100 SPIoutputCS(0)
    /// @test group TEST10_SCAN_0100 SPIread16bits() expect 0x1000 mask 0xF000 // expect 0x1xxx (channel ID 1)
    /// @test group TEST10_SCAN_0100 SPIoutputCS(1)
    /// @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0x2xxx (channel ID 2)")
    /// @test group TEST10_SCAN_0100 SPIoutputCS(0)
    /// @test group TEST10_SCAN_0100 SPIread16bits() expect 0x2000 mask 0xF000 // expect 0x2xxx (channel ID 2)
    /// @test group TEST10_SCAN_0100 SPIoutputCS(1)
    /// @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0x3xxx (channel ID 3)")
    /// @test group TEST10_SCAN_0100 SPIoutputCS(0)
    /// @test group TEST10_SCAN_0100 SPIread16bits() expect 0x3000 mask 0xF000 // expect 0x3xxx (channel ID 3)
    /// @test group TEST10_SCAN_0100 SPIoutputCS(1)
    /// @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0x4xxx (channel ID 4)")
    /// @test group TEST10_SCAN_0100 SPIoutputCS(0)
    /// @test group TEST10_SCAN_0100 SPIread16bits() expect 0x4000 mask 0xF000 // expect 0x4xxx (channel ID 4)
    /// @test group TEST10_SCAN_0100 SPIoutputCS(1)
    /// @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0x5xxx (channel ID 5)")
    /// @test group TEST10_SCAN_0100 SPIoutputCS(0)
    /// @test group TEST10_SCAN_0100 SPIread16bits() expect 0x5000 mask 0xF000 // expect 0x5xxx (channel ID 5)
    /// @test group TEST10_SCAN_0100 SPIoutputCS(1)
    /// @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0x6xxx (channel ID 6)")
    /// @test group TEST10_SCAN_0100 SPIoutputCS(0)
    /// @test group TEST10_SCAN_0100 SPIread16bits() expect 0x6000 mask 0xF000 // expect 0x6xxx (channel ID 6)
    /// @test group TEST10_SCAN_0100 SPIoutputCS(1)
    /// @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0x7xxx (channel ID 7)")
    /// @test group TEST10_SCAN_0100 SPIoutputCS(0)
    /// @test group TEST10_SCAN_0100 SPIread16bits() expect 0x7000 mask 0xF000 // expect 0x7xxx (channel ID 7)
    /// @test group TEST10_SCAN_0100 SPIoutputCS(1)
    /// @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0x8xxx (channel ID 8)")
    /// @test group TEST10_SCAN_0100 SPIoutputCS(0)
    /// @test group TEST10_SCAN_0100 SPIread16bits() expect 0x8000 mask 0xF000 // expect 0x8xxx (channel ID 8)
    /// @test group TEST10_SCAN_0100 SPIoutputCS(1)
    /// @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0x9xxx (channel ID 9)")
    /// @test group TEST10_SCAN_0100 SPIoutputCS(0)
    /// @test group TEST10_SCAN_0100 SPIread16bits() expect 0x9000 mask 0xF000 // expect 0x9xxx (channel ID 9)
    /// @test group TEST10_SCAN_0100 SPIoutputCS(1)
    /// @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0xaxxx (channel ID 10)")
    /// @test group TEST10_SCAN_0100 SPIoutputCS(0)
    /// @test group TEST10_SCAN_0100 SPIread16bits() expect 0xA000 mask 0xF000 // expect 0xaxxx (channel ID 10)
    /// @test group TEST10_SCAN_0100 SPIoutputCS(1)
    /// @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0xbxxx (channel ID 11)")
    /// @test group TEST10_SCAN_0100 SPIoutputCS(0)
    /// @test group TEST10_SCAN_0100 SPIread16bits() expect 0xB000 mask 0xF000 // expect 0xbxxx (channel ID 11)
    /// @test group TEST10_SCAN_0100 SPIoutputCS(1)
    /// @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0xcxxx (channel ID 12)")
    /// @test group TEST10_SCAN_0100 SPIoutputCS(0)
    /// @test group TEST10_SCAN_0100 SPIread16bits() expect 0xC000 mask 0xF000 // expect 0xcxxx (channel ID 12)
    /// @test group TEST10_SCAN_0100 SPIoutputCS(1)
    /// @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0xdxxx (channel ID 13)")
    /// @test group TEST10_SCAN_0100 SPIoutputCS(0)
    /// @test group TEST10_SCAN_0100 SPIread16bits() expect 0xD000 mask 0xF000 // expect 0xdxxx (channel ID 13)
    /// @test group TEST10_SCAN_0100 SPIoutputCS(1)
    /// @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0xexxx (channel ID 14)")
    /// @test group TEST10_SCAN_0100 SPIoutputCS(0)
    /// @test group TEST10_SCAN_0100 SPIread16bits() expect 0xE000 mask 0xF000 // expect 0xexxx (channel ID 14)
    /// @test group TEST10_SCAN_0100 SPIoutputCS(1)
    /// @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0xfxxx (channel ID 15)")
    /// @test group TEST10_SCAN_0100 SPIoutputCS(0)
    /// @test group TEST10_SCAN_0100 SPIread16bits() expect 0xF000 mask 0xF000 // expect 0xfxxx (channel ID 15)
    /// @test group TEST10_SCAN_0100 SPIoutputCS(1)
    ///     //
    /// @test group TEST4_SCAN_0100 // 4 ch=15 pm=0 id=1 -- ScanStandardExternalCloc (enabled by default)
    /// @test group TEST4_SCAN_0100 tinyTester.print("4 ch=15 pm=0 id=1 -- ScanStandardExternalClock")
    /// @test group TEST4_SCAN_0100 tinyTester.print("channelNumber_0_15 = 15")
    /// @test group TEST4_SCAN_0100 channelNumber_0_15 = 15
    /// @test group TEST4_SCAN_0100 tinyTester.print("PowerManagement_0_2 = 0")
    /// @test group TEST4_SCAN_0100 PowerManagement_0_2 = 0 // 0=Normal
    /// @test group TEST4_SCAN_0100 tinyTester.print("chan_id_0_1 = 1")
    /// @test group TEST4_SCAN_0100 chan_id_0_1 = 1 // misoData16 = CH[3:0] DATA[11:0]
    /// @test group TEST4_SCAN_0100 tinyTester.print("ScanStandardExternalClock() expect 16")
    /// @test group TEST4_SCAN_0100 ScanStandardExternalClock() expect 16 // Scan_0100_StandardExt
    /// @test group TEST4_SCAN_0100 tinyTester.print("NumWords expect 16")
    /// @test group TEST4_SCAN_0100 NumWords expect 16
    /// @test group TEST4_SCAN_0100 ReadAINcode()
    /// @test group TEST4_SCAN_0100 tinyTester.print("Verify RAW_misoData16[0..15]>>12&0x000F == 0..15 channelId")
    /// @test group TEST4_SCAN_0100 RAW_misoData16[0]  expect 0x0000 mask 0xF000 // expect 0x0xxx (channel ID 0)
    /// @test group TEST4_SCAN_0100 RAW_misoData16[1]  expect 0x1000 mask 0xF000 // expect 0x1xxx (channel ID 1)
    /// @test group TEST4_SCAN_0100 RAW_misoData16[2]  expect 0x2000 mask 0xF000 // expect 0x2xxx (channel ID 2)
    /// @test group TEST4_SCAN_0100 RAW_misoData16[3]  expect 0x3000 mask 0xF000 // expect 0x3xxx (channel ID 3)
    /// @test group TEST4_SCAN_0100 RAW_misoData16[4]  expect 0x4000 mask 0xF000 // expect 0x4xxx (channel ID 4)
    /// @test group TEST4_SCAN_0100 RAW_misoData16[5]  expect 0x5000 mask 0xF000 // expect 0x5xxx (channel ID 5)
    /// @test group TEST4_SCAN_0100 RAW_misoData16[6]  expect 0x6000 mask 0xF000 // expect 0x6xxx (channel ID 6)
    /// @test group TEST4_SCAN_0100 RAW_misoData16[7]  expect 0x7000 mask 0xF000 // expect 0x7xxx (channel ID 7)
    /// @test group TEST4_SCAN_0100 RAW_misoData16[8]  expect 0x8000 mask 0xF000 // expect 0x8xxx (channel ID 8)
    /// @test group TEST4_SCAN_0100 RAW_misoData16[9]  expect 0x9000 mask 0xF000 // expect 0x9xxx (channel ID 9)
    /// @test group TEST4_SCAN_0100 RAW_misoData16[10] expect 0xA000 mask 0xF000 // expect 0xaxxx (channel ID 10)
    /// @test group TEST4_SCAN_0100 RAW_misoData16[11] expect 0xB000 mask 0xF000 // expect 0xbxxx (channel ID 11)
    /// @test group TEST4_SCAN_0100 RAW_misoData16[12] expect 0xC000 mask 0xF000 // expect 0xcxxx (channel ID 12)
    /// @test group TEST4_SCAN_0100 RAW_misoData16[13] expect 0xD000 mask 0xF000 // expect 0xdxxx (channel ID 13)
    /// @test group TEST4_SCAN_0100 RAW_misoData16[14] expect 0xE000 mask 0xF000 // expect 0xexxx (channel ID 14)
    /// @test group TEST4_SCAN_0100 RAW_misoData16[15] expect 0xF000 mask 0xF000 // expect 0xfxxx (channel ID 15)
    ///     // 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("
    ///       MOSI <-- 1000_0000_0000_0000  ADC_CONFIGURATION REFSEL=0 SPM[1:0]=0 ECHO=0");
    /// @test tinyTester.print("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
    /// @test SPIoutputCS(0)
    /// @test SPIwrite16bits(0x8000)
    /// @test SPIoutputCS(1)
    ///     //
    ///     cmdLine.serial().printf(
    ///         "
    ///       MOSI <-- 0010_0111_1010_0100  ADC_MODE_CONTROL Scan_0100_StandardExt CHSEL=15 RESET=1 CHANID=1");
    /// @test tinyTester.print("0010_0111_1010_0100  ADC_MODE_CONTROL Scan_0100_StandardExt")
    /// @test tinyTester.print("                                      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
    /// @test SPIoutputCS(0)
    /// @test SPIwrite16bits(0x27a4)
    /// @test SPIoutputCS(1)
    ///     //
    /// @future test SPIoutputCS(0)
    /// @future SPIread16bits() expect 0x0000
    /// @future SPIread16bits() expect 0x0000 mask 0xF000
    /// @future test SPIread16bits() expect 0x1000 mask 0xF000
    /// @future test SPIread16bits() expect 0x2000 mask 0xF000
    /// @future test SPIread16bits() expect 0x3000 mask 0xF000
    /// @future test SPIread16bits() expect 0x4000 mask 0xF000
    /// @future test SPIread16bits() expect 0x5000 mask 0xF000
    /// @future test SPIread16bits() expect 0x6000 mask 0xF000
    /// @future test SPIread16bits() expect 0x7000 mask 0xF000
    /// @future test SPIread16bits() expect 0x8000 mask 0xF000
    /// @future test SPIread16bits() expect 0x9000 mask 0xF000
    /// @future test SPIread16bits() expect 0xA000 mask 0xF000
    /// @future test SPIread16bits() expect 0xB000 mask 0xF000
    /// @future test SPIread16bits() expect 0xC000 mask 0xF000
    /// @future test SPIread16bits() expect 0xD000 mask 0xF000
    /// @future test SPIread16bits() expect 0xE000 mask 0xF000
    /// @future test SPIread16bits() expect 0xF000 mask 0xF000
    /// @future test SPIoutputCS(1)
    ///     //
    ///     for (int channelIndex = 0; channelIndex < 16; channelIndex++) {
    ///         //~ cmdLine.serial().printf("
    ///       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)
    ///         {
    ///             tinyTester.FAIL();
    ///             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
    ///         {
    ///             tinyTester.PASS();
    ///             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);
    ///         }
    ///     }
    /// @future test tinyTester.print("NumWords=16")
    /// @future test NumWords=16
    /// @future test tinyTester.print("ReadAINcode()")
    /// @future test ReadAINcode()
    /// @future test tinyTester.print("TODO: expect RAW_misoData16[0..15]>>12&0x000F == 0..15 channelId")
    /// @future test RAW_misoData16[0] expect 0x0000 mask 0xF000
    /// @future test RAW_misoData16[1] expect 0x1000 mask 0xF000
    /// @future test RAW_misoData16[2] expect 0x2000 mask 0xF000
    /// @future test RAW_misoData16[3] expect 0x3000 mask 0xF000
    ///     //
    ///     // MAX11131 SelfTest: MAX11131 Supports Internal Clock Modes (CNVST, EOC)
    ///     cmdLine.serial().printf("
    /// ");
    ///     cmdLine.serial().printf(
    ///         "
    ///       1.1: Test Scan_0011_StandardInt -- verify Internal Clock signals (CNVST, EOC)");
    /// @test group TEST11_SCAN_0011 // 1.1: Test Scan_0011_StandardInt -- verify Internal Clock CNVST,EOC (enabled by default)
    /// @test group TEST11_SCAN_0011 tinyTester.print("1.1: Test Scan_0011_StandardInt -- verify Internal Clock CNVST,EOC")
    ///     cmdLine.serial().printf("
    ///       MAX11131.Init()");
    /// @future test tinyTester.print("_______")
    /// @test group TEST11_SCAN_0011 Init();
    /// @test group TEST11_SCAN_0011 SPIoutputCS(0); // drive CS low
    ///     g_MAX11131_device.RAW_misoData16[0] = g_MAX11131_device.SPIread16bits();
    /// @test group TEST11_SCAN_0011 group TEST11_SCAN_0011 SPIoutputCS(1); // drive CS high
    /// //
    ///     // tinyTester.DigitalIn_Read_Expect_WarnOnly replaces SelfTest_MAX11131_EOC_expect
    ///     tinyTester.DigitalIn_Read_Expect_WarnOnly(EOCb_pin, "EOC", 1, "initial value before sending commands");
    /// //
    ///     // 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("
    ///       MOSI <-- 1000_0000_0000_0000  ADC_CONFIGURATION REFSEL=0 SPM[1:0]=0 ECHO=0");
    /// @test group TEST11_SCAN_0011 tinyTester.print("1000_0000_0000_0000  ADC_CONFIGURATION REFSEL=0 SPM[1:0]=0 ECHO=0")
    /// @test group TEST11_SCAN_0011 SPIoutputCS(0); // drive CS low
    /// @test group TEST11_SCAN_0011 SPIwrite16bits(0x8000);
    /// @test group TEST11_SCAN_0011 SPIoutputCS(1); // drive CS high
    ///     //
    ///     cmdLine.serial().printf(
    ///         "
    ///       MOSI <-- 0001_1001_1010_0000  ADC_MODE_CONTROL Scan_0011_StandardInt CHSEL=3 RESET=1 SWCNV=0");
    /// @test group TEST11_SCAN_0011 tinyTester.print("0001_1001_1010_0000  ADC_MODE_CONTROL Scan_0011_StandardInt")
    /// @test group TEST11_SCAN_0011 tinyTester.print("                                      CHSEL=3 RESET=1 SWCNV=0")
    /// @test group TEST11_SCAN_0011 SPIoutputCS(0); // drive CS low
    /// @test group TEST11_SCAN_0011 SPIwrite16bits(0x19a0);
    /// @test group TEST11_SCAN_0011 SPIoutputCS(1); // drive CS high
    ///     //
    ///     for (int channelIndex = 0; channelIndex < 4; channelIndex++) {
    ///         //~ cmdLine.serial().printf("
    ///       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
    ///         // tinyTester.DigitalIn_Read_Expect_WarnOnly replaces SelfTest_MAX11131_EOC_expect
    ///         tinyTester.DigitalIn_Read_Expect_WarnOnly(EOCb_pin, "EOC", 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
    ///         // tinyTester.DigitalIn_Read_Expect_WarnOnly replaces SelfTest_MAX11131_EOC_expect
    ///         tinyTester.DigitalIn_Read_Expect_WarnOnly(EOCb_pin, "EOC", 1, "after SPI read");
    ///         int expect_channelId = channelIndex;
    ///         int actual_channelId = (g_MAX11131_device.RAW_misoData16[channelIndex] >> 12) & 0x000F;
    ///         if (actual_channelId != expect_channelId)
    ///         {
    ///             tinyTester.FAIL();
    ///             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
    ///         {
    ///             tinyTester.PASS();
    ///             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);
    ///         }
    ///     }
    ///     //
    ///     // 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("
    /// ");
    ///     cmdLine.serial().printf("
    ///       2.0: Test Fixture: MAX541 connected to spi2 (P2.4 P2.5 P2.7)?");
    /// @future test tinyTester.print("_______")
    ///     bool SelfTest_has_max541 = false;
    ///     // Check actual MAX541 reference voltage
    ///     cmdLine.serial().printf("
    ///       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
    ///     tinyTester.Wait_Output_Settling(); // wait for MAX541 to settle
    ///     //
    ///     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("
    ///       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 = 2.7f;
    ///         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("
    ///       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("
    /// ");
    ///         cmdLine.serial().printf("
    ///       2.1: TODO1: Check MAX11131 reference voltage using Scan_0001_Manual");
    /// @future test tinyTester.print("_______")
    ///         voltageV = 1.0f;
    ///         SelfTest_MAX541_Voltage(cmdLine, max541, voltageV);
    ///         cmdLine.serial().printf("
    ///       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("
    ///       MAX11131.channelNumber_0_15=%d", g_MAX11131_device.channelNumber_0_15);
    ///         cmdLine.serial().printf("
    ///       MAX11131.PowerManagement_0_2=%d", g_MAX11131_device.PowerManagement_0_2);
    ///         cmdLine.serial().printf("
    ///       MAX11131.chan_id_0_1=%d", g_MAX11131_device.chan_id_0_1);
    ///         g_MAX11131_device.NumWords = g_MAX11131_device.ScanManual();
    ///         cmdLine.serial().printf("
    ///       MAX11131.ScanManual -- NumWords = %d",
    ///                                 g_MAX11131_device.NumWords);
    ///         g_MAX11131_device.NumWords = g_MAX11131_device.ScanManual();
    ///         g_MAX11131_device.ReadAINcode();
    ///         cmdLine.serial().printf("
    ///       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("
    ///       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("
    ///       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);
    /// //
    ///         // tinyTester.Wait_Output_Settling replaces wait_ms
    ///         tinyTester.Wait_Output_Settling();
    ///         // tinyTester.AnalogIn0_Read_Expect_voltageV replaces SelfTest_AnalogInput_Expect_ch_V
    ///         tinyTester.err_threshold = 0.100;
    ///         tinyTester.AnalogIn0_Read_Expect_voltageV(voltageV);
    /// //
    ///     }
    ///     //
    ///     if (SelfTest_has_max541) {
    ///         voltageV = 1.0f;
    ///         SelfTest_MAX541_Voltage(cmdLine, max541, voltageV);
    ///     }
    ///     cmdLine.serial().printf("
    /// ");
    ///     cmdLine.serial().printf("
    ///       3.1: Test Scan_0001_Manual");
    /// @future test tinyTester.print("_______")
    ///     cmdLine.serial().printf("
    ///       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("
    ///       MAX11131.channelNumber_0_15=%d", g_MAX11131_device.channelNumber_0_15);
    /// @future test tinyTester.print("_______")
    ///     cmdLine.serial().printf("
    ///       MAX11131.PowerManagement_0_2=%d", g_MAX11131_device.PowerManagement_0_2);
    /// @future test tinyTester.print("_______")
    ///     cmdLine.serial().printf("
    ///       MAX11131.chan_id_0_1=%d", g_MAX11131_device.chan_id_0_1);
    /// @future test tinyTester.print("_______")
    ///     g_MAX11131_device.NumWords = g_MAX11131_device.ScanManual();
    ///     cmdLine.serial().printf("
    ///       MAX11131.ScanManual -- NumWords = %d",
    ///                             g_MAX11131_device.NumWords);
    /// @future test tinyTester.print("_______")
    ///     // 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("
    ///       MAX11131.ReadAINcode");
    /// @future test tinyTester.print("_______")
    ///     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);
    /// //
    ///     // tinyTester.Wait_Output_Settling replaces wait_ms
    ///     tinyTester.Wait_Output_Settling();
    ///     // tinyTester.AnalogIn0_Read_Expect_voltageV replaces SelfTest_AnalogInput_Expect_ch_V
    ///     tinyTester.err_threshold = 0.100;
    ///     tinyTester.AnalogIn0_Read_Expect_voltageV(voltageV);
    /// //
    ///     //
    ///     cmdLine.serial().printf("
    /// ");
    ///     cmdLine.serial().printf("
    ///       3.4: Test Scan_0100_StandardExternalClock");
    /// @future test tinyTester.print("_______")
    ///     cmdLine.serial().printf("
    ///       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("
    ///       MAX11131.channelNumber_0_15=%d", g_MAX11131_device.channelNumber_0_15);
    /// @future test tinyTester.print("_______")
    ///     cmdLine.serial().printf("
    ///       MAX11131.PowerManagement_0_2=%d", g_MAX11131_device.PowerManagement_0_2);
    /// @future test tinyTester.print("_______")
    ///     cmdLine.serial().printf("
    ///       MAX11131.chan_id_0_1=%d", g_MAX11131_device.chan_id_0_1);
    /// @future test tinyTester.print("_______")
    ///     g_MAX11131_device.NumWords = g_MAX11131_device.ScanStandardExternalClock();
    ///     cmdLine.serial().printf("
    ///       MAX11131.ScanStandardExternalClock -- NumWords = %d",
    ///                             g_MAX11131_device.NumWords);
    /// @future test tinyTester.print("_______")
    ///     // 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("
    ///       MAX11131.ReadAINcode");
    /// @future test tinyTester.print("_______")
    ///     // @post RAW_misoData16[index] contains the raw SPI Master-In,Slave-Out data
    ///     // @post AINcode[NUM_CHANNELS] contains the latest readings in LSBs
    ///     // expect g_MAX11131_device.NumWords == g_MAX11131_device.channelNumber_0_15 + 1;
    ///     // expect RAW_misoData16[index] msnybble 0,1,2,3,...
    ///     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);
    ///     // tinyTester.Wait_Output_Settling replaces wait_ms
    ///     tinyTester.Wait_Output_Settling();
    ///     // tinyTester.AnalogIn0_Read_Expect_voltageV replaces SelfTest_AnalogInput_Expect_ch_V
    ///     tinyTester.err_threshold = 0.100;
    ///     tinyTester.AnalogIn0_Read_Expect_voltageV(voltageV);
    ///     // 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);
    ///
    ///
    ///
    void Init(void);

    //----------------------------------------
    /// Menu item 'IS'
    /// ADC Channels AIN(channelId), AIN(channelId+1) = Both Single-Ended, Unipolar
    /// Full Scale = VREF
    /// Voltage per LSB count = VREF/4096
    /// AIN(channelId) is a Single-Ended input using Unipolar transfer function.
    /// AIN(channelId+1) is a Single-Ended input using Unipolar transfer function.
    /// If PDIFF_COM_1, both are Pseudo-Differential with REF- as common.
    /// AIN(channelId) voltage must always be between 0 and VREF.
    /// AIN(channelId+1) voltage must always be between 0 and VREF.
    ///
    void Reconfigure_SingleEnded(int channel_0_15);

    //----------------------------------------
    /// Menu item 'IU'
    /// ADC Channels AIN(channelId), AIN(channelId+1) = Differential Unipolar (AIN(channelId) > AIN(channelId+1))
    /// Full Scale = VREF
    /// Voltage per LSB count = VREF/4096
    /// AIN(channelId), AIN(channelId+1) are a Differential pair using Unipolar transfer function.
    /// AIN(channelId) voltage must always be between 0 and VREF.
    /// AIN(channelId+1) voltage must always be between 0 and VREF.
    ///
    void Reconfigure_DifferentialUnipolar(int channel_0_15);

    //----------------------------------------
    /// Menu item 'IB'
    /// ADC Channels AIN(channelId), AIN(channelId+1) = Differential Bipolar
    /// Full Scale = VREF
    /// Voltage per LSB count = VREF/4096
    /// AIN(channelId), AIN(channelId+1) are a Differential pair using Bipolar transfer function with range (+/-)(1/2)Vref
    /// AIN(channelId) voltage must always be between 0 and VREF.
    /// AIN(channelId+1) voltage must always be between 0 and VREF.
    ///
    void Reconfigure_DifferentialBipolarFSVref(int channel_0_15);

    //----------------------------------------
    /// Menu item 'IR'
    /// ADC Channels AIN(channelId), AIN(channelId+1) = Differential Bipolar
    /// Full Scale = 2 * VREF
    /// Voltage per LSB count = VREF/2048
    /// AIN(channelId), AIN(channelId+1) are a Differential pair using Bipolar transfer function with range (+/-)Vref
    /// AIN(channelId) voltage must always be between 0 and VREF.
    /// AIN(channelId+1) voltage must always be between 0 and VREF.
    ///
    void Reconfigure_DifferentialBipolarFS2Vref(int channel_0_15);

    //----------------------------------------
    /// SCAN_0000_NOP
    ///
    /// Shift 16 bits out of ADC, without changing configuration.
    /// Note: @return data format depends on CHAN_ID bit:
    ///     "CH[3:0] DATA[11:0]" when CHAN_ID = 1, or
    ///     "0 DATA[11:0] x x x" when CHAN_ID = 0.
    int16_t ScanRead(void);

    //----------------------------------------
    /// SCAN_0000_NOP
    ///
    /// Read raw ADC codes from device into AINcode[] and RAW_misoData16[].
    /// If internal clock mode with SWCNV=0, measurements will be triggered using CNVST pin.
    ///
    /// @pre one of the Scan functions was called, setting g_MAX11131_device.NumWords
    /// @param[in] g_MAX11131_device.NumWords: number of words to be read from the FIFO
    /// @post g_MAX11131_device.RAW_misoData16[index] contains the raw SPI Master-In,Slave-Out data
    /// @post g_MAX11131_device.AINcode[NUM_CHANNELS] contains the latest readings in LSBs
    ///
    void ReadAINcode(void);

    //----------------------------------------
    /// Sign-Extend a right-aligned MAX11131 code into a signed 2's complement value.
    /// Supports the bipolar transfer functions.
    /// @param[in] value_u12: raw 12-bit MAX11131 code (right justified).
    /// @return sign-extended 2's complement value.
    ///
    int32_t TwosComplementValue(uint32_t regValue);

    //----------------------------------------
    /// Return the physical voltage corresponding to MAX11131 code.
    /// Does not perform any offset or gain correction.
    /// @pre g_MAX11131_device.VRef = Voltage of REF input, in Volts
    /// @param[in] value_u12: raw 12-bit MAX11131 code (right justified).
    /// @param[in] channelId: AIN channel number.
    /// @return physical voltage corresponding to MAX11131 code.
    ///
    double VoltageOfCode(int16_t value_u12, int channelId);

    //----------------------------------------
    /// SCAN_0001_Manual
    ///
    /// Measure ADC channel channelNumber_0_15 once.
    /// External clock mode.
    /// @param[in] g_MAX11131_device.channelNumber_0_15: AIN Channel Number
    /// @param[in] g_MAX11131_device.PowerManagement_0_2: 0=Normal, 1=AutoShutdown, 2=AutoStandby
    /// @param[in] g_MAX11131_device.chan_id_0_1: ADC_MODE_CONTROL.CHAN_ID
    /// @return number of ScanRead() words needed to retrieve the data.
    /// @post NumWords = number of words to be read from the FIFO
    /// For external clock modes, the data format depends on CHAN_ID.
    ///     when CHAN_ID = 0: misoData16 = 0 DATA[11:0] x x x
    ///     when CHAN_ID = 1: misoData16 = CH[3:0] DATA[11:0]
    ///
    int ScanManual(void);

    //----------------------------------------
    /// SCAN_0010_Repeat
    ///
    /// Measure ADC channel channelNumber_0_15 repeatedly with averaging.
    /// Internal clock mode.
    /// @param[in] g_MAX11131_device.channelNumber_0_15: AIN Channel Number
    /// @param[in] g_MAX11131_device.average_0_4_8_16_32: Number of samples averaged per ScanRead() word.
    ///     average_0_4_8_16_32=0 to disable averaging.
    /// @param[in] g_MAX11131_device.nscan_4_8_12_16: Number of ScanRead() words to report.
    /// @param[in] g_MAX11131_device.swcnv_0_1: ADC_MODE_CONTROL.SWCNV
    ///     SWCNV=0: trigger measurement by driving CNVST pin low.
    ///         Minimum active-low pulse duration of 5ns. (AIN14 is not available)
    ///     SWCNV=1: trigger measurement on SPI CS rising edge.
    ///         CS must be held low for minimum of 17 SCLK cycles.
    ///         CNVST pin is not used. (AIN14 is available)
    /// @param[in] g_MAX11131_device.PowerManagement_0_2: 0=Normal, 1=AutoShutdown, 2=AutoStandby
    /// @return number of ScanRead() words needed to retrieve the data.
    /// @post NumWords = number of words to be read from the FIFO
    /// For internal clock modes, the data format always includes the channel address.
    ///     misoData16 = CH[3:0] DATA[11:0]
    ///
    int ScanRepeat(void);

    //----------------------------------------
    /// SCAN_0011_StandardInternalClock
    ///
    /// Measure ADC channels in sequence from AIN0 to channelNumber_0_15.
    /// Internal clock mode.
    /// @param[in] g_MAX11131_device.channelNumber_0_15: AIN Channel Number
    /// @param[in] g_MAX11131_device.average_0_4_8_16_32: Number of samples averaged per ScanRead() word.
    ///     average_0_4_8_16_32=0 to disable averaging.
    /// @param[in] g_MAX11131_device.PowerManagement_0_2: 0=Normal, 1=AutoShutdown, 2=AutoStandby
    /// @param[in] g_MAX11131_device.swcnv_0_1: ADC_MODE_CONTROL.SWCNV
    ///     SWCNV=0: trigger measurement by driving CNVST pin low.
    ///         Minimum active-low pulse duration of 5ns. (AIN14 is not available)
    ///     SWCNV=1: trigger measurement on SPI CS rising edge.
    ///         CS must be held low for minimum of 17 SCLK cycles.
    ///         CNVST pin is not used. (AIN14 is available)
    /// @return number of ScanRead() words needed to retrieve the data.
    /// @post NumWords = number of words to be read from the FIFO
    /// For internal clock modes, the data format always includes the channel address.
    ///     misoData16 = CH[3:0] DATA[11:0]
    ///
    int ScanStandardInternalClock(void);

    //----------------------------------------
    /// SCAN_0100_StandardExternalClock
    ///
    /// Measure ADC channels in sequence from AIN0 to channelNumber_0_15.
    /// External clock mode.
    /// @param[in] g_MAX11131_device.channelNumber_0_15: AIN Channel Number
    /// @param[in] g_MAX11131_device.PowerManagement_0_2: 0=Normal, 1=AutoShutdown, 2=AutoStandby
    /// @param[in] g_MAX11131_device.chan_id_0_1: ADC_MODE_CONTROL.CHAN_ID
    /// @return number of ScanRead() words needed to retrieve the data.
    /// @post NumWords = number of words to be read from the FIFO
    /// For external clock modes, the data format depends on CHAN_ID.
    ///     when CHAN_ID = 0: misoData16 = 0 DATA[11:0] x x x
    ///     when CHAN_ID = 1: misoData16 = CH[3:0] DATA[11:0]
    ///
    int ScanStandardExternalClock(void);

    //----------------------------------------
    /// SCAN_0101_UpperInternalClock
    ///
    /// Measure ADC channels in sequence from channelNumber_0_15 to AIN15.
    /// Internal clock mode.
    /// @param[in] g_MAX11131_device.channelNumber_0_15: AIN Channel Number
    /// @param[in] g_MAX11131_device.average_0_4_8_16_32: Number of samples averaged per ScanRead() word.
    ///     average_0_4_8_16_32=0 to disable averaging.
    /// @param[in] g_MAX11131_device.PowerManagement_0_2: 0=Normal, 1=AutoShutdown, 2=AutoStandby
    /// @param[in] g_MAX11131_device.swcnv_0_1: ADC_MODE_CONTROL.SWCNV
    ///     SWCNV=0: trigger measurement by driving CNVST pin low.
    ///         Minimum active-low pulse duration of 5ns. (AIN14 is not available)
    ///     SWCNV=1: trigger measurement on SPI CS rising edge.
    ///         CS must be held low for minimum of 17 SCLK cycles.
    ///         CNVST pin is not used. (AIN14 is available)
    /// @return number of ScanRead() words needed to retrieve the data.
    /// @post NumWords = number of words to be read from the FIFO
    /// For internal clock modes, the data format always includes the channel address.
    ///     misoData16 = CH[3:0] DATA[11:0]
    ///
    int ScanUpperInternalClock(void);

    //----------------------------------------
    /// SCAN_0110_UpperExternalClock
    ///
    /// Measure ADC channels in sequence from channelNumber_0_15 to AIN15.
    /// External clock mode.
    /// @param[in] g_MAX11131_device.channelNumber_0_15: AIN Channel Number
    /// @param[in] g_MAX11131_device.PowerManagement_0_2: 0=Normal, 1=AutoShutdown, 2=AutoStandby
    /// @param[in] g_MAX11131_device.chan_id_0_1: ADC_MODE_CONTROL.CHAN_ID
    /// @return number of ScanRead() words needed to retrieve the data.
    /// @post NumWords = number of words to be read from the FIFO
    /// For external clock modes, the data format depends on CHAN_ID.
    ///     when CHAN_ID = 0: misoData16 = 0 DATA[11:0] x x x
    ///     when CHAN_ID = 1: misoData16 = CH[3:0] DATA[11:0]
    ///
    int ScanUpperExternalClock(void);

    //----------------------------------------
    /// SCAN_0111_CustomInternalClock
    ///
    /// Measure selected ADC channels in sequence from AIN0 to AIN15,
    ///     using only the channels enabled by enabledChannelsMask.
    ///     Bit 0x0001 enables AIN0.
    ///     Bit 0x0002 enables AIN1.
    ///     Bit 0x0004 enables AIN2.
    ///     Bit 0x0008 enables AIN3.
    ///     Bit 0x0010 enables AIN4.
    ///     Bit 0x0020 enables AIN5.
    ///     Bit 0x0040 enables AIN6.
    ///     Bit 0x0080 enables AIN7.
    ///     Bit 0x0100 enables AIN8.
    ///     Bit 0x0200 enables AIN9.
    ///     Bit 0x0400 enables AIN10.
    ///     Bit 0x0800 enables AIN11.
    ///     Bit 0x1000 enables AIN12.
    ///     Bit 0x2000 enables AIN13.
    ///     Bit 0x4000 enables AIN14.
    ///     Bit 0x8000 enables AIN15.
    /// Internal clock mode.
    /// @param[in] g_MAX11131_device.enabledChannelsMask: Bitmap of AIN Channels to scan.
    /// @param[in] g_MAX11131_device.average_0_4_8_16_32: Number of samples averaged per ScanRead() word.
    ///     average_0_4_8_16_32=0 to disable averaging.
    /// @param[in] g_MAX11131_device.PowerManagement_0_2: 0=Normal, 1=AutoShutdown, 2=AutoStandby
    /// @param[in] g_MAX11131_device.swcnv_0_1: ADC_MODE_CONTROL.SWCNV
    ///     SWCNV=0: trigger measurement by driving CNVST pin low.
    ///         Minimum active-low pulse duration of 5ns. (AIN14 is not available)
    ///     SWCNV=1: trigger measurement on SPI CS rising edge.
    ///         CS must be held low for minimum of 17 SCLK cycles.
    ///         CNVST pin is not used. (AIN14 is available)
    /// @return number of ScanRead() words needed to retrieve the data.
    /// @post NumWords = number of words to be read from the FIFO
    /// For internal clock modes, the data format always includes the channel address.
    ///     misoData16 = CH[3:0] DATA[11:0]
    ///
    int ScanCustomInternalClock(void);

    //----------------------------------------
    /// SCAN_1000_CustomExternalClock
    ///
    /// Measure selected ADC channels in sequence from AIN0 to AIN15,
    ///     using only the channels enabled by enabledChannelsMask.
    ///     Bit 0x0001 enables AIN0.
    ///     Bit 0x0002 enables AIN1.
    ///     Bit 0x0004 enables AIN2.
    ///     Bit 0x0008 enables AIN3.
    ///     Bit 0x0010 enables AIN4.
    ///     Bit 0x0020 enables AIN5.
    ///     Bit 0x0040 enables AIN6.
    ///     Bit 0x0080 enables AIN7.
    ///     Bit 0x0100 enables AIN8.
    ///     Bit 0x0200 enables AIN9.
    ///     Bit 0x0400 enables AIN10.
    ///     Bit 0x0800 enables AIN11.
    ///     Bit 0x1000 enables AIN12.
    ///     Bit 0x2000 enables AIN13.
    ///     Bit 0x4000 enables AIN14.
    ///     Bit 0x8000 enables AIN15.
    /// External clock mode.
    /// @param[in] g_MAX11131_device.enabledChannelsMask: Bitmap of AIN Channels to scan.
    /// @param[in] g_MAX11131_device.PowerManagement_0_2: 0=Normal, 1=AutoShutdown, 2=AutoStandby
    /// @param[in] g_MAX11131_device.chan_id_0_1: ADC_MODE_CONTROL.CHAN_ID
    /// @return number of ScanRead() words needed to retrieve the data.
    /// @post NumWords = number of words to be read from the FIFO
    /// For external clock modes, the data format depends on CHAN_ID.
    ///     when CHAN_ID = 0: misoData16 = 0 DATA[11:0] x x x
    ///     when CHAN_ID = 1: misoData16 = CH[3:0] DATA[11:0]
    ///
    int ScanCustomExternalClock(void);

    //----------------------------------------
    /// SCAN_1001_SampleSetExternalClock
    ///
    /// Measure ADC channels in an arbitrary pattern.
    ///     Channels can be visited in any order, with repetition allowed.
    /// External clock mode.
    /// @pre g_MAX11131_device.enabledChannelsPatternLength_1_256: number of channel selections
    /// @pre g_MAX11131_device.enabledChannelsPattern: array containing channel selection pattern
    ///     In the array, one channel select per byte.
    ///     In the SPI interface, immediately after SAMPLESET register is written,
    ///     each byte encodes two channelNumber selections.
    ///     The high 4 bits encode the first channelNumber.
    ///     (((enabledChannelsPattern[0]) & 0x0F) << 4) | ((enabledChannelsPattern[1]) & 0x0F)
    ///     If it is an odd number of channels, additional nybbles will be ignored.
    ///     CS will be asserted low during the entire SAMPLESET pattern selection.
    /// @param[in] g_MAX11131_device.enabledChannelsPattern: array of channel select, one channel per byte
    /// @param[in] g_MAX11131_device.PowerManagement_0_2: 0=Normal, 1=AutoShutdown, 2=AutoStandby
    /// @param[in] g_MAX11131_device.chan_id_0_1: ADC_MODE_CONTROL.CHAN_ID
    /// @return number of ScanRead() words needed to retrieve the data.
    /// @post NumWords = number of words to be read from the FIFO
    /// For external clock modes, the data format depends on CHAN_ID.
    ///     when CHAN_ID = 0: misoData16 = 0 DATA[11:0] x x x
    ///     when CHAN_ID = 1: misoData16 = CH[3:0] DATA[11:0]
    ///
    int ScanSampleSetExternalClock(void);

    //----------------------------------------
    /// Example configure and perform some measurements in ScanManual mode.
    /// @param[out] pd_mean = address for double mean (avearge)
    /// @param[out] pd_variance = address for double variance (variance)
    /// @param[out] pd_stddev = address for double stddev (standard deviation)
    /// @param[out] pd_Sx = address for double Sx (sum of all X)
    /// @param[out] pd_Sxx = address for double Sxx (sum of squares of each X)
    void Example_ScanManual(int channelNumber_0_15, int nWords, 
  double* pd_mean, double* pd_variance, double* pd_stddev, 
  double* pd_Sx, double* pd_Sxx);

}; // end of class MAX11131

#endif // __MAX11131_H__

// End of file