Maxim Integrated MAX5715 12-bit 4-channel voltage-output DAC

Dependents:   MAX5715BOB_Tester MAX5715BOB_12bit_4ch_SPI_DAC MAX5715BOB_Serial_Tester

Revision:
0:777851395940
Child:
3:a3f0518094f4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MAX5715.cpp	Thu May 23 22:18:03 2019 +0000
@@ -0,0 +1,1113 @@
+// /*******************************************************************************
+// * Copyright (C) 2019 Maxim Integrated Products, Inc., All Rights Reserved.
+// *
+// * Permission is hereby granted, free of charge, to any person obtaining a
+// * copy of this software and associated documentation files (the "Software"),
+// * to deal in the Software without restriction, including without limitation
+// * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// * and/or sell copies of the Software, and to permit persons to whom the
+// * Software is furnished to do so, subject to the following conditions:
+// *
+// * The above copyright notice and this permission notice shall be included
+// * in all copies or substantial portions of the Software.
+// *
+// * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
+// * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// * OTHER DEALINGS IN THE SOFTWARE.
+// *
+// * Except as contained in this notice, the name of Maxim Integrated
+// * Products, Inc. shall not be used except as stated in the Maxim Integrated
+// * Products, Inc. Branding Policy.
+// *
+// * The mere transfer of this software does not imply any licenses
+// * of trade secrets, proprietary technology, copyrights, patents,
+// * trademarks, maskwork rights, or any other form of intellectual
+// * property whatsoever. Maxim Integrated Products, Inc. retains all
+// * ownership rights.
+// *******************************************************************************
+// */
+// *********************************************************************
+// @file MAX5715.cpp
+// *********************************************************************
+// Device Driver file
+// DO NOT EDIT; except areas designated "CUSTOMIZE". Automatically generated file.
+// generated by XMLSystemOfDevicesToMBED.py
+// System Name = ExampleSystem
+// System Description = Device driver example
+
+#include "MAX5715.h"
+
+// Device Name = MAX5715
+// Device Description = Ultra-Small, 12-Bit, 4-Channel, Buffered Output Voltage DAC with Internal Reference and SPI Interface
+// Device Manufacturer = Maxim Integrated
+// Device PartNumber = MAX5715AAUD+
+// Device RegValue_Width = DataWidth16bit_HL
+//
+// DAC NumChannels = 4
+// DAC ResolutionBits = 12
+//
+// SPI CS = ActiveLow
+// SPI FrameStart = CS
+// SPI CPOL = 1
+// SPI CPHA = 0
+// SPI MOSI and MISO Data are both stable on Falling edge of SCLK
+// SPI SCLK Idle High
+// SPI SCLKMaxMHz = 50
+// SPI SCLKMinMHz = 0
+//
+// InputPin Name = LDAC#
+// InputPin Description = Dedicated Active-Low Asynchronous Load DAC.
+// InputPin Function = Trigger
+//
+// InputPin Name = CLR#
+// InputPin Description = Active-Low Clear Input.
+// InputPin Function = Trigger
+//
+// InputPin Name = REF
+// InputPin Description = Reference Voltage Input/Output.
+//     Software selectable to be external reference or internal 2.048V, 2.500V, or 4.096V reference.
+//     Default is external reference mode.
+// InputPin Function = Reference
+//
+// OutputPin Name = OUTA
+// OutputPin Description = Buffered Channel A DAC Output
+// OutputPin Function = Analog
+//
+// OutputPin Name = OUTB
+// OutputPin Description = Buffered Channel B DAC Output
+// OutputPin Function = Analog
+//
+// OutputPin Name = OUTC
+// OutputPin Description = Buffered Channel C DAC Output
+// OutputPin Function = Analog
+//
+// OutputPin Name = OUTD
+// OutputPin Description = Buffered Channel D DAC Output
+// OutputPin Function = Analog
+//
+// OutputPin Name = RDY#
+// OutputPin Description = SPI RDY Output. In daisy-chained applications connect RDY to the CSB of the next device in the chain.
+// OutputPin Function = DaisyChain
+//
+// SupplyPin Name = VDD
+// SupplyPin Description = Supply Voltage Input. Bypass VDD with a 0.1uF capacitor to GND.
+// SupplyPin VinMax = 5.5
+// SupplyPin VinMin = 2.7 (unless configured DAC VRefInternal = 4.096V, then VinMin = 4.5V)
+// SupplyPin Function = Analog
+//
+// SupplyPin Name = VDDIO
+// SupplyPin Description = Digital Interface Power-Supply Input
+// SupplyPin VinMax = 5.5
+// SupplyPin VinMin = 1.8
+// SupplyPin Function = Digital
+//
+
+// CODE GENERATOR: class constructor definition
+MAX5715::MAX5715(SPI &spi, DigitalOut &cs_pin, // SPI interface
+                 // CODE GENERATOR: class constructor definition gpio InputPin pins
+                 DigitalOut &LDACb_pin, // Digital Trigger Input to MAX5715 device
+                 DigitalOut &CLRb_pin, // Digital Trigger Input to MAX5715 device
+                 // AnalogOut &REF_pin, // Reference Input to MAX5715 device
+                 // CODE GENERATOR: class constructor definition gpio OutputPin pins
+                 // AnalogIn &OUTA_pin, // Analog Output from MAX5715 device
+                 // AnalogIn &OUTB_pin, // Analog Output from MAX5715 device
+                 // AnalogIn &OUTC_pin, // Analog Output from MAX5715 device
+                 // AnalogIn &OUTD_pin, // Analog Output from MAX5715 device
+                 // DigitalIn &RDYb_pin, // Digital DaisyChain Output from MAX5715 device
+                 // CODE GENERATOR: class constructor definition ic_variant
+                 MAX5715_ic_t ic_variant)
+    // CODE GENERATOR: class constructor initializer list
+    : m_spi(spi), m_cs_pin(cs_pin), // SPI interface
+    // CODE GENERATOR: class constructor initializer list gpio InputPin pins
+    m_LDACb_pin(LDACb_pin), // Digital Trigger Input to MAX5715 device
+    m_CLRb_pin(CLRb_pin), // Digital Trigger Input to MAX5715 device
+    // m_REF_pin(REF_pin), // Reference Input to MAX5715 device
+    // CODE GENERATOR: class constructor initializer list gpio OutputPin pins
+    // m_OUTA_pin(OUTA_pin), // Analog Output from MAX5715 device
+    // m_OUTB_pin(OUTB_pin), // Analog Output from MAX5715 device
+    // m_OUTC_pin(OUTC_pin), // Analog Output from MAX5715 device
+    // m_OUTD_pin(OUTD_pin), // Analog Output from MAX5715 device
+    // m_RDYb_pin(RDYb_pin), // Digital DaisyChain Output from MAX5715 device
+    // CODE GENERATOR: class constructor initializer list ic_variant
+    m_ic_variant(ic_variant)
+{
+    // CODE GENERATOR: class constructor definition SPI interface initialization
+    //
+    // SPI CS = ActiveLow
+    // SPI FrameStart = CS
+    m_SPI_cs_state = 1;
+    m_cs_pin = m_SPI_cs_state;
+
+    // SPI CPOL = 1
+    // SPI CPHA = 0
+    // SPI MOSI and MISO Data are both stable on Falling edge of SCLK
+    // SPI SCLK Idle High
+    m_SPI_dataMode = 2; //SPI_MODE2; // CPOL=1,CPHA=0: Falling Edge stable; SCLK idle High
+    m_spi.format(8,m_SPI_dataMode);         // int bits_must_be_8, int mode=0_3 CPOL=0,CPHA=0
+
+    // SPI SCLKMaxMHz = 50
+    // SPI SCLKMinMHz = 0
+    //#define SPI_SCLK_Hz 48000000 // 48MHz
+    //#define SPI_SCLK_Hz 24000000 // 24MHz
+    //#define SPI_SCLK_Hz 12000000 // 12MHz
+    //#define SPI_SCLK_Hz 4000000 // 4MHz
+    //#define SPI_SCLK_Hz 2000000 // 2MHz
+    //#define SPI_SCLK_Hz 1000000 // 1MHz
+    m_SPI_SCLK_Hz = 12000000; // 12MHz; MAX5715 limit is 50MHz
+    m_spi.frequency(m_SPI_SCLK_Hz);
+
+    // TODO1: CODE GENERATOR: class constructor definition gpio InputPin (Input to device) initialization
+    //
+    m_LDACb_pin = 1; // output logic high -- initial value in constructor
+    m_CLRb_pin = 1; // output logic high -- initial value in constructor
+}
+
+// CODE GENERATOR: class destructor definition
+MAX5715::~MAX5715()
+{
+    // do nothing
+}
+
+// CODE GENERATOR: spi_frequency setter definition
+// set SPI SCLK frequency
+void MAX5715::spi_frequency(int spi_sclk_Hz)
+{
+    m_SPI_SCLK_Hz = spi_sclk_Hz;
+    m_spi.frequency(m_SPI_SCLK_Hz);
+}
+
+// CODE GENERATOR: omit global g_MAX5715_device
+// CODE GENERATOR: extern function declarations
+// CODE GENERATOR: extern function requirement MAX5715::SPIoutputCS
+// Assert SPI Chip Select
+// SPI chip-select for MAX5715
+//
+void MAX5715::SPIoutputCS(int isLogicHigh)
+{
+    // CODE GENERATOR: extern function definition for function SPIoutputCS
+    // CODE GENERATOR: extern function definition for standard SPI interface function SPIoutputCS(int isLogicHigh)
+    m_SPI_cs_state = isLogicHigh;
+    m_cs_pin = m_SPI_cs_state;
+}
+
+// CODE GENERATOR: extern function requirement MAX5715::SPIwrite24bits
+// SPI write 24 bits
+// SPI interface to MAX5715 shift 24 bits mosiData into MAX5715 DIN
+//
+void MAX5715::SPIwrite24bits(int8_t mosiData8_FF0000, int16_t mosiData16_00FFFF)
+{
+    // CODE GENERATOR: extern function definition for function SPIwrite24bits
+    // TODO1: CODE GENERATOR: extern function definition for standard SPI interface function SPIwrite24bits(int8_t mosiData8_FF0000, int16_t mosiData16_00FFFF)
+    size_t byteCount = 3;
+    static char mosiData[3];
+    static char misoData[3];
+    mosiData[0] = mosiData8_FF0000;
+    mosiData[1] = (char)((mosiData16_00FFFF >> 8) & 0xFF); // MSByte
+    mosiData[2] = (char)((mosiData16_00FFFF >> 0) & 0xFF); // LSByte
+    //
+    // Arduino: begin critical section: noInterrupts() masks all interrupt sources; end critical section with interrupts()
+    //~ noInterrupts();
+    //
+    //~ digitalWrite(Scope_Trigger_Pin, LOW); // diagnostic Scope_Trigger_Pin
+    //
+    unsigned int numBytesTransferred = m_spi.write(mosiData, byteCount, misoData, byteCount);
+    //~ SPI.transfer(mosiData8_FF0000);
+    //~ SPI.transfer(mosiData16_00FF00);
+    //~ SPI.transfer(mosiData16_0000FF);
+    //
+    //~ digitalWrite(Scope_Trigger_Pin, HIGH); // diagnostic Scope_Trigger_Pin
+    //
+    // Arduino: begin critical section: noInterrupts() masks all interrupt sources; end critical section with interrupts()
+    //~ interrupts();
+    //
+    // VERIFY: SPIwrite24bits print diagnostic information
+    //cmdLine.serial().printf(" MOSI->"));
+    //cmdLine.serial().printf(" 0x"));
+    //Serial.print( (mosiData8_FF0000 & 0xFF), HEX);
+    //cmdLine.serial().printf(" 0x"));
+    //Serial.print( (mosiData16_00FF00 & 0xFF), HEX);
+    //cmdLine.serial().printf(" 0x"));
+    //Serial.print( (mosiData16_0000FF & 0xFF), HEX);
+    // hex dump mosiData[0..byteCount-1]
+#if HAS_MICROUSBSERIAL
+    cmdLine_microUSBserial.serial().printf("\r\nSPI");
+    if (byteCount > 7) {
+        cmdLine_microUSBserial.serial().printf(" byteCount:%d", byteCount);
+    }
+    cmdLine_microUSBserial.serial().printf(" MOSI->");
+    for (unsigned int byteIndex = 0; byteIndex < byteCount; byteIndex++)
+    {
+        cmdLine_microUSBserial.serial().printf(" 0x%2.2X", mosiData[byteIndex]);
+    }
+    // hex dump misoData[0..byteCount-1]
+    cmdLine_microUSBserial.serial().printf("  MISO<-");
+    for (unsigned int byteIndex = 0; byteIndex < numBytesTransferred; byteIndex++)
+    {
+        cmdLine_microUSBserial.serial().printf(" 0x%2.2X", misoData[byteIndex]);
+    }
+    cmdLine_microUSBserial.serial().printf(" ");
+#endif
+#if HAS_DAPLINK_SERIAL
+    cmdLine_DAPLINKserial.serial().printf("\r\nSPI");
+    if (byteCount > 7) {
+        cmdLine_DAPLINKserial.serial().printf(" byteCount:%d", byteCount);
+    }
+    cmdLine_DAPLINKserial.serial().printf(" MOSI->");
+    for (unsigned int byteIndex = 0; byteIndex < byteCount; byteIndex++)
+    {
+        cmdLine_DAPLINKserial.serial().printf(" 0x%2.2X", mosiData[byteIndex]);
+    }
+    // hex dump misoData[0..byteCount-1]
+    cmdLine_DAPLINKserial.serial().printf("  MISO<-");
+    for (unsigned int byteIndex = 0; byteIndex < numBytesTransferred; byteIndex++)
+    {
+        cmdLine_DAPLINKserial.serial().printf(" 0x%2.2X", misoData[byteIndex]);
+    }
+    cmdLine_DAPLINKserial.serial().printf(" ");
+#endif
+    // VERIFY: DIAGNOSTIC: print MAX5715 device register write
+    // TODO: MAX5715_print_register_verbose(mosiData8_FF0000, mosiData16_00FFFF);
+    //
+    // int misoData16 = (misoData16_FF00 << 8) | misoData16_00FF;
+    // return misoData16;
+}
+
+// TODO1: CODE GENERATOR: extern function GPIOoutputLDACb alias LDACboutputValue
+// CODE GENERATOR: extern function requirement MAX5715::LDACboutputValue
+// Assert MAX5715 LDAC pin : High = inactive, Low = load DAC.
+//
+void MAX5715::LDACboutputValue(int isLogicHigh)
+{
+    // CODE GENERATOR: extern function definition for function LDACboutputValue
+    // TODO1: CODE GENERATOR: extern function definition for gpio interface function LDACboutputValue
+    // TODO1: CODE GENERATOR: gpio pin LDACb assuming member function m_LDACb_pin
+    // TODO1: CODE GENERATOR: gpio direction output
+    // m_LDACb_pin.output(); // only applicable to DigitalInOut
+    // TODO1: CODE GENERATOR: gpio function Value
+    m_LDACb_pin = isLogicHigh;
+}
+
+// TODO1: CODE GENERATOR: extern function GPIOoutputCLRb alias CLRboutputValue
+// CODE GENERATOR: extern function requirement MAX5715::CLRboutputValue
+// Assert MAX5715 CLR pin : High = inactive, Low = clear DAC.
+//
+void MAX5715::CLRboutputValue(int isLogicHigh)
+{
+    // CODE GENERATOR: extern function definition for function CLRboutputValue
+    // TODO1: CODE GENERATOR: extern function definition for gpio interface function CLRboutputValue
+    // TODO1: CODE GENERATOR: gpio pin CLRb assuming member function m_CLRb_pin
+    // TODO1: CODE GENERATOR: gpio direction output
+    // m_CLRb_pin.output(); // only applicable to DigitalInOut
+    // TODO1: CODE GENERATOR: gpio function Value
+    m_CLRb_pin = isLogicHigh;
+}
+
+// CODE GENERATOR: class member function definitions
+//----------------------------------------
+// Initialize device
+// @return 1 on success; 0 on failure
+uint8_t MAX5715::Init(void)
+{
+    
+    //----------------------------------------
+    // Initialize device
+          //----------------------------------------
+          // Perform Software Reset
+          if (!SW_RESET()) {
+            return 0; // failure
+          }
+          //----------------------------------------
+          // Turn on the reference output pin
+          REF(REF_AlwaysOn_2V500);
+          //
+          //~ Serial.println(F(" success"));
+          //~ return;
+          return 1; // success
+}
+
+//----------------------------------------
+// Return the DAC register value corresponding to physical voltage.
+// Does not perform any offset or gain correction.
+//
+// @pre VRef = Voltage of REF input, in Volts
+// @param[in] voltage = physical voltage in Volts
+// @return raw 12-bit MAX5715 code (right justified).
+uint16_t MAX5715::DACCodeOfVoltage(double voltageV)
+{
+    
+    //----------------------------------------
+    // Linear map min and max endpoints
+    const double MaxScaleVoltage = VRef; // voltage of maximum code 0x0fff
+    const double MinScaleVoltage = 0.0; // voltage of minimum code 0x000
+    const uint16_t FULL_SCALE_CODE_12BIT = 0x0fff;
+    const uint16_t MaxCode = FULL_SCALE_CODE_12BIT;
+    const uint16_t MinCode = 0x000;
+    double codeFraction = (voltageV - MinScaleVoltage) / (MaxScaleVoltage - MinScaleVoltage);
+    double dacRegValueIdeal = ((codeFraction * (double)(MaxCode - MinCode + 1)) + MinCode + 0.5);
+    uint16_t dacRegValue = (uint16_t)dacRegValueIdeal;
+    if (dacRegValueIdeal > MaxCode)
+    {
+        dacRegValue = MaxCode;
+    } else if (dacRegValueIdeal < MinCode)
+    {
+        dacRegValue = MinCode;
+    }
+    return dacRegValue;
+}
+
+//----------------------------------------
+// Return the physical voltage corresponding to DAC register.
+// Does not perform any offset or gain correction.
+//
+// @pre VRef = Voltage of REF input, in Volts
+// @param[in] value_u12: raw 12-bit MAX5715 code (right justified).
+// @return physical voltage corresponding to MAX5715 code.
+double MAX5715::VoltageOfCode(uint16_t value_u12)
+{
+    
+    //----------------------------------------
+    // Linear map min and max endpoints
+    double MaxScaleVoltage = VRef; // voltage of maximum code 0x0fff
+    double MinScaleVoltage = 0.0; // voltage of minimum code 0x000
+    const uint16_t FULL_SCALE_CODE_12BIT = 0x0fff;
+    const uint16_t MaxCode = FULL_SCALE_CODE_12BIT;
+    const uint16_t MinCode = 0x000;
+    double codeFraction = ((double)value_u12 - MinCode) / (MaxCode - MinCode + 1);
+    return MinScaleVoltage + ((MaxScaleVoltage - MinScaleVoltage) * codeFraction);
+}
+
+//----------------------------------------
+// CMD_1000_0000_dddd_dddd_dddd_0000_CODEall
+//
+// Writes data to all CODE registers
+// @post updates g_MAX5815_device.Shadow_0010_nnnn_CODE[0..3]
+// @post updates g_MAX5815_device.CODE[0..3]
+void MAX5715::CODEall(uint16_t dacCodeLsbs)
+{
+    
+    //----------------------------------------
+    // Define command code
+    uint8_t command_regAddress = CMD_1000_0000_dddd_dddd_dddd_0000_CODEall;
+    uint16_t regValue = (dacCodeLsbs << 4); // left-align dddd_dddd_dddd_0000
+    
+    //----------------------------------------
+    // SPI write 8-bit regAddress and 16-bit regValue
+    // int16_t mosiData16 = ((command_regAddress << 8) & 0xFF00) | ((regValue >> 8) & 0xFF);
+    // int8_t mosiData8_0000FF = (regValue & 0xFF);
+    SPIoutputCS(0);
+    SPIwrite24bits(command_regAddress, regValue);
+    SPIoutputCS(1);
+    
+    //----------------------------------------
+    // shadow of write-only register CODE 0010_nnnn[channel_0_3]
+    // Each bit of channels_bitmask_DCBA maps to an index of g_MAX5815_device.Shadow_0010_nnnn_CODE[0..3]
+    if (channels_bitmask_DCBA & (1 << 0)) {
+        CODE[0] = dacCodeLsbs;
+        Shadow_0010_nnnn_CODE[0] = regValue;
+    }
+    if (channels_bitmask_DCBA & (1 << 1)) {
+        CODE[1] = dacCodeLsbs;
+        Shadow_0010_nnnn_CODE[1] = regValue;
+    }
+    if (channels_bitmask_DCBA & (1 << 2)) {
+        CODE[2] = dacCodeLsbs;
+        Shadow_0010_nnnn_CODE[2] = regValue;
+    }
+    if (channels_bitmask_DCBA & (1 << 3)) {
+        CODE[3] = dacCodeLsbs;
+        Shadow_0010_nnnn_CODE[3] = regValue;
+    }
+}
+
+//----------------------------------------
+// CMD_0000_nnnn_dddd_dddd_dddd_0000_CODEn
+//
+// Writes data to the selected CODE register(s)
+//
+// @param[in] channel_0_3 = DAC Selection: 0=OUTA, 1=OUTB, 2=OUTC, 3=OUTD, 4..15=ALL OUTA,OUTB,OUTC,OUTD
+// @post updates g_MAX5815_device.Shadow_0010_nnnn_CODE[0..3]
+// @post updates g_MAX5815_device.CODE[0..3]
+void MAX5715::CODEn(uint8_t channel_0_3, uint16_t dacCodeLsbs)
+{
+    
+    //----------------------------------------
+    // update channel selection from channel_0_3
+    channelNumber_0_3 = channel_0_3;
+    switch (channelNumber_0_3) {
+      case 0: 
+        channels_bitmask_DCBA = 0x01; // OUTA only
+        break;
+      case 1: 
+        channels_bitmask_DCBA = 0x02; // OUTB only
+        break;
+      case 2: 
+        channels_bitmask_DCBA = 0x04; // OUTC only
+        break;
+      case 3: 
+        channels_bitmask_DCBA = 0x08; // OUTD only
+        break;
+      default: 
+        channels_bitmask_DCBA = 0x0F; // ALL OUTA,OUTB,OUTC,OUTD
+    }
+    
+    //----------------------------------------
+    // Define command code
+    uint8_t command_regAddress = CMD_0000_nnnn_dddd_dddd_dddd_0000_CODEn | (channel_0_3 & 0x0F);
+    uint16_t regValue = (dacCodeLsbs << 4); // left-align dddd_dddd_dddd_0000
+    
+    //----------------------------------------
+    // SPI write 8-bit regAddress and 16-bit regValue
+    // int16_t mosiData16 = ((command_regAddress << 8) & 0xFF00) | ((regValue >> 8) & 0xFF);
+    // int8_t mosiData8_0000FF = (regValue & 0xFF);
+    SPIoutputCS(0);
+    SPIwrite24bits(command_regAddress, regValue);
+    SPIoutputCS(1);
+    
+    //----------------------------------------
+    // shadow of write-only register CODE 0010_nnnn[channel_0_3]
+    // Each bit of channels_bitmask_DCBA maps to an index of g_MAX5815_device.Shadow_0010_nnnn_CODE[0..3]
+    if (channels_bitmask_DCBA & (1 << 0)) {
+        CODE[0] = dacCodeLsbs;
+        Shadow_0010_nnnn_CODE[0] = regValue;
+    }
+    if (channels_bitmask_DCBA & (1 << 1)) {
+        CODE[1] = dacCodeLsbs;
+        Shadow_0010_nnnn_CODE[1] = regValue;
+    }
+    if (channels_bitmask_DCBA & (1 << 2)) {
+        CODE[2] = dacCodeLsbs;
+        Shadow_0010_nnnn_CODE[2] = regValue;
+    }
+    if (channels_bitmask_DCBA & (1 << 3)) {
+        CODE[3] = dacCodeLsbs;
+        Shadow_0010_nnnn_CODE[3] = regValue;
+    }
+}
+
+//----------------------------------------
+// CMD_1000_0010_dddd_dddd_dddd_0000_CODEallLOADall
+//
+// Simultaneously writes data to all CODE registers while updating all DAC registers
+// @post updates g_MAX5815_device.Shadow_0010_nnnn_CODE[0..3]
+// @post updates g_MAX5815_device.CODE[0..3]
+void MAX5715::CODEallLOADall(uint16_t dacCodeLsbs)
+{
+    
+    //----------------------------------------
+    // Define command code
+    uint8_t command_regAddress = CMD_1000_0010_dddd_dddd_dddd_0000_CODEallLOADall;
+    uint16_t regValue = (dacCodeLsbs << 4); // left-align dddd_dddd_dddd_0000
+    
+    //----------------------------------------
+    // SPI write 8-bit regAddress and 16-bit regValue
+    // int16_t mosiData16 = ((command_regAddress << 8) & 0xFF00) | ((regValue >> 8) & 0xFF);
+    // int8_t mosiData8_0000FF = (regValue & 0xFF);
+    SPIoutputCS(0);
+    SPIwrite24bits(command_regAddress, regValue);
+    SPIoutputCS(1);
+    
+    //----------------------------------------
+    // shadow of write-only register CODE 0010_nnnn[channel_0_3]
+    // Each bit of channels_bitmask_DCBA maps to an index of g_MAX5815_device.Shadow_0010_nnnn_CODE[0..3]
+    CODE[0] = dacCodeLsbs;
+    Shadow_0010_nnnn_CODE[0] = regValue;
+    CODE[1] = dacCodeLsbs;
+    Shadow_0010_nnnn_CODE[1] = regValue;
+    CODE[2] = dacCodeLsbs;
+    Shadow_0010_nnnn_CODE[2] = regValue;
+    CODE[3] = dacCodeLsbs;
+    Shadow_0010_nnnn_CODE[3] = regValue;
+}
+
+//----------------------------------------
+// CMD_0010_nnnn_dddd_dddd_dddd_0000_CODEnLOADall
+//
+// Simultaneously writes data to the selected CODE register(s) while updating all DAC registers.
+//
+// @param[in] channel_0_3 = DAC Selection: 0=OUTA, 1=OUTB, 2=OUTC, 3=OUTD, 4..15=ALL OUTA,OUTB,OUTC,OUTD
+// @post updates g_MAX5815_device.Shadow_0010_nnnn_CODE[0..3]
+// @post updates g_MAX5815_device.CODE[0..3]
+void MAX5715::CODEnLOADall(uint8_t channel_0_3, uint16_t dacCodeLsbs)
+{
+    
+    //----------------------------------------
+    // update channel selection from channel_0_3
+    channelNumber_0_3 = channel_0_3;
+    switch (channelNumber_0_3) {
+      case 0: 
+        channels_bitmask_DCBA = 0x01; // OUTA only
+        break;
+      case 1: 
+        channels_bitmask_DCBA = 0x02; // OUTB only
+        break;
+      case 2: 
+        channels_bitmask_DCBA = 0x04; // OUTC only
+        break;
+      case 3: 
+        channels_bitmask_DCBA = 0x08; // OUTD only
+        break;
+      default: 
+        channels_bitmask_DCBA = 0x0F; // ALL OUTA,OUTB,OUTC,OUTD
+    }
+    
+    //----------------------------------------
+    // Define command code
+    uint8_t command_regAddress = CMD_0010_nnnn_dddd_dddd_dddd_0000_CODEnLOADall | (channel_0_3 & 0x0F);
+    uint16_t regValue = (dacCodeLsbs << 4); // left-align dddd_dddd_dddd_0000
+    
+    //----------------------------------------
+    // SPI write 8-bit regAddress and 16-bit regValue
+    // int16_t mosiData16 = ((command_regAddress << 8) & 0xFF00) | ((regValue >> 8) & 0xFF);
+    // int8_t mosiData8_0000FF = (regValue & 0xFF);
+    SPIoutputCS(0);
+    SPIwrite24bits(command_regAddress, regValue);
+    SPIoutputCS(1);
+    
+    //----------------------------------------
+    // shadow of write-only register CODE 0010_nnnn[channel_0_3]
+    // Each bit of channels_bitmask_DCBA maps to an index of g_MAX5815_device.Shadow_0010_nnnn_CODE[0..3]
+    if (channels_bitmask_DCBA & (1 << 0)) {
+        CODE[0] = dacCodeLsbs;
+        Shadow_0010_nnnn_CODE[0] = regValue;
+    }
+    if (channels_bitmask_DCBA & (1 << 1)) {
+        CODE[1] = dacCodeLsbs;
+        Shadow_0010_nnnn_CODE[1] = regValue;
+    }
+    if (channels_bitmask_DCBA & (1 << 2)) {
+        CODE[2] = dacCodeLsbs;
+        Shadow_0010_nnnn_CODE[2] = regValue;
+    }
+    if (channels_bitmask_DCBA & (1 << 3)) {
+        CODE[3] = dacCodeLsbs;
+        Shadow_0010_nnnn_CODE[3] = regValue;
+    }
+}
+
+//----------------------------------------
+// CMD_0011_nnnn_dddd_dddd_dddd_0000_CODEnLOADn
+//
+// Simultaneously writes data to the selected CODE register(s) while updating selected DAC register(s)
+//
+// @param[in] channel_0_3 = DAC Selection: 0=OUTA, 1=OUTB, 2=OUTC, 3=OUTD, 4..15=ALL OUTA,OUTB,OUTC,OUTD
+// @post updates g_MAX5815_device.Shadow_0010_nnnn_CODE[0..3]
+// @post updates g_MAX5815_device.CODE[0..3]
+void MAX5715::CODEnLOADn(uint8_t channel_0_3, uint16_t dacCodeLsbs)
+{
+    
+    //----------------------------------------
+    // update channel selection from channel_0_3
+    channelNumber_0_3 = channel_0_3;
+    switch (channelNumber_0_3) {
+      case 0: 
+        channels_bitmask_DCBA = 0x01; // OUTA only
+        break;
+      case 1: 
+        channels_bitmask_DCBA = 0x02; // OUTB only
+        break;
+      case 2: 
+        channels_bitmask_DCBA = 0x04; // OUTC only
+        break;
+      case 3: 
+        channels_bitmask_DCBA = 0x08; // OUTD only
+        break;
+      default: 
+        channels_bitmask_DCBA = 0x0F; // ALL OUTA,OUTB,OUTC,OUTD
+    }
+    
+    //----------------------------------------
+    // Define command code
+    uint8_t command_regAddress = CMD_0011_nnnn_dddd_dddd_dddd_0000_CODEnLOADn | (channel_0_3 & 0x0F);
+    uint16_t regValue = (dacCodeLsbs << 4); // left-align dddd_dddd_dddd_0000
+    
+    //----------------------------------------
+    // SPI write 8-bit regAddress and 16-bit regValue
+    // int16_t mosiData16 = ((command_regAddress << 8) & 0xFF00) | ((regValue >> 8) & 0xFF);
+    // int8_t mosiData8_0000FF = (regValue & 0xFF);
+    SPIoutputCS(0);
+    SPIwrite24bits(command_regAddress, regValue);
+    SPIoutputCS(1);
+    
+    //----------------------------------------
+    // shadow of write-only register CODE 0010_nnnn[channel_0_3]
+    // Each bit of channels_bitmask_DCBA maps to an index of g_MAX5815_device.Shadow_0010_nnnn_CODE[0..3]
+    if (channels_bitmask_DCBA & (1 << 0)) {
+        CODE[0] = dacCodeLsbs;
+        Shadow_0010_nnnn_CODE[0] = regValue;
+    }
+    if (channels_bitmask_DCBA & (1 << 1)) {
+        CODE[1] = dacCodeLsbs;
+        Shadow_0010_nnnn_CODE[1] = regValue;
+    }
+    if (channels_bitmask_DCBA & (1 << 2)) {
+        CODE[2] = dacCodeLsbs;
+        Shadow_0010_nnnn_CODE[2] = regValue;
+    }
+    if (channels_bitmask_DCBA & (1 << 3)) {
+        CODE[3] = dacCodeLsbs;
+        Shadow_0010_nnnn_CODE[3] = regValue;
+    }
+}
+
+//----------------------------------------
+// CMD_0110_0000_0000_dcba_0000_0000_CONFIGn_LATCHED
+//
+// Sets the DAC Latch Mode of the selected DACs.
+// Only DACS with a 1 in the selection bit are updated by the command.
+// LD_EN = 0: DAC latch is operational (LOAD and LDAC controlled)
+//
+// @param[in] channels_bitmask_DCBA = channel select bitmap
+//     bit 1000 = channel D
+//     bit 0100 = channel C
+//     bit 0010 = channel B
+//     bit 0001 = channel A
+void MAX5715::CONFIGn_LATCHED(uint8_t channels_bitmask_DCBA)
+{
+    
+    //----------------------------------------
+    // update channel selection from channels_bitmask_DCBA
+    channels_bitmask_DCBA = channels_bitmask_DCBA;
+    if (channels_bitmask_DCBA == 0x0F) {
+        channelNumber_0_3 = 0x0F; // ALL OUTA,OUTB,OUTC,OUTD
+    }
+    else if ((channels_bitmask_DCBA & 0x01) != 0) {
+        channelNumber_0_3 = 0x00; // OUTA only
+    }
+    else if ((channels_bitmask_DCBA & 0x02) != 0) {
+        channelNumber_0_3 = 0x01; // OUTB only
+    }
+    else if ((channels_bitmask_DCBA & 0x04) != 0) {
+        channelNumber_0_3 = 0x02; // OUTC only
+    }
+    else {
+        channelNumber_0_3 = 0x03; // OUTD only
+    }
+    
+    //----------------------------------------
+    // Define command code
+    uint8_t command_regAddress = CMD_0110_0000_0000_dcba_0000_0000_CONFIGn_LATCHED;
+    uint16_t regValue = ((channels_bitmask_DCBA & 0x0F) << 8); // align field 0000_dcba_0000_0000
+    
+    //----------------------------------------
+    // SPI write 8-bit regAddress and 16-bit regValue
+    // int16_t mosiData16 = ((command_regAddress << 8) & 0xFF00) | ((regValue >> 8) & 0xFF);
+    // int8_t mosiData8_0000FF = (regValue & 0xFF);
+    SPIoutputCS(0);
+    SPIwrite24bits(command_regAddress, regValue);
+    SPIoutputCS(1);
+}
+
+//----------------------------------------
+// CMD_0110_0001_0000_dcba_0000_0000_CONFIGn_TRANSPARENT
+//
+// Sets the DAC Latch Mode of the selected DACs.
+// Only DACS with a 1 in the selection bit are updated by the command.
+// LD_EN = 1: DAC latch is transparent
+//
+// @param[in] channels_bitmask_DCBA = channel select bitmap
+//     bit 1000 = channel D
+//     bit 0100 = channel C
+//     bit 0010 = channel B
+//     bit 0001 = channel A
+void MAX5715::CONFIGn_TRANSPARENT(uint8_t channels_bitmask_DCBA)
+{
+    
+    //----------------------------------------
+    // update channel selection from channels_bitmask_DCBA
+    channels_bitmask_DCBA = channels_bitmask_DCBA;
+    if (channels_bitmask_DCBA == 0x0F) {
+        channelNumber_0_3 = 0x0F; // ALL OUTA,OUTB,OUTC,OUTD
+    }
+    else if ((channels_bitmask_DCBA & 0x01) != 0) {
+        channelNumber_0_3 = 0x00; // OUTA only
+    }
+    else if ((channels_bitmask_DCBA & 0x02) != 0) {
+        channelNumber_0_3 = 0x01; // OUTB only
+    }
+    else if ((channels_bitmask_DCBA & 0x04) != 0) {
+        channelNumber_0_3 = 0x02; // OUTC only
+    }
+    else {
+        channelNumber_0_3 = 0x03; // OUTD only
+    }
+    
+    //----------------------------------------
+    // Define command code
+    uint8_t command_regAddress = CMD_0110_0001_0000_dcba_0000_0000_CONFIGn_TRANSPARENT;
+    uint16_t regValue = ((channels_bitmask_DCBA & 0x0F) << 8); // align field 0000_dcba_0000_0000
+    
+    //----------------------------------------
+    // SPI write 8-bit regAddress and 16-bit regValue
+    // int16_t mosiData16 = ((command_regAddress << 8) & 0xFF00) | ((regValue >> 8) & 0xFF);
+    // int8_t mosiData8_0000FF = (regValue & 0xFF);
+    SPIoutputCS(0);
+    SPIwrite24bits(command_regAddress, regValue);
+    SPIoutputCS(1);
+}
+
+//----------------------------------------
+// CMD_0110_1000_0000_0000_0000_0000_CONFIGall_LATCHED
+//
+// Sets the DAC Latch Mode of all DACs.
+// LD_EN = 0: DAC latch is operational (LOAD and LDAC controlled)
+void MAX5715::CONFIGall_LATCHED(void)
+{
+    
+    //----------------------------------------
+    // Define command code
+    uint8_t command_regAddress = CMD_0110_1000_0000_0000_0000_0000_CONFIGall_LATCHED;
+    uint16_t regValue = 0; // 0000_0000_0000_0000
+    
+    //----------------------------------------
+    // SPI write 8-bit regAddress and 16-bit regValue
+    // int16_t mosiData16 = ((command_regAddress << 8) & 0xFF00) | ((regValue >> 8) & 0xFF);
+    // int8_t mosiData8_0000FF = (regValue & 0xFF);
+    SPIoutputCS(0);
+    SPIwrite24bits(command_regAddress, regValue);
+    SPIoutputCS(1);
+}
+
+//----------------------------------------
+// CMD_0110_1001_0000_0000_0000_0000_CONFIGall_TRANSPARENT
+//
+// Sets the DAC Latch Mode of all DACs.
+// LD_EN = 1: DAC latch is transparent
+void MAX5715::CONFIGall_TRANSPARENT(void)
+{
+    
+    //----------------------------------------
+    // Define command code
+    uint8_t command_regAddress = CMD_0110_1001_0000_0000_0000_0000_CONFIGall_TRANSPARENT;
+    uint16_t regValue = 0; // 0000_0000_0000_0000
+    
+    //----------------------------------------
+    // SPI write 8-bit regAddress and 16-bit regValue
+    // int16_t mosiData16 = ((command_regAddress << 8) & 0xFF00) | ((regValue >> 8) & 0xFF);
+    // int8_t mosiData8_0000FF = (regValue & 0xFF);
+    SPIoutputCS(0);
+    SPIwrite24bits(command_regAddress, regValue);
+    SPIoutputCS(1);
+}
+
+//----------------------------------------
+// CMD_1000_0001_0000_0000_0000_0000_LOADall
+//
+// Updates all DAC latches with current CODE register data
+void MAX5715::LOADall(void)
+{
+    
+    //----------------------------------------
+    // Define command code
+    uint8_t command_regAddress = CMD_1000_0001_0000_0000_0000_0000_LOADall;
+    uint16_t regValue = 0; // 0000_0000_0000_0000
+    
+    //----------------------------------------
+    // SPI write 8-bit regAddress and 16-bit regValue
+    // int16_t mosiData16 = ((command_regAddress << 8) & 0xFF00) | ((regValue >> 8) & 0xFF);
+    // int8_t mosiData8_0000FF = (regValue & 0xFF);
+    SPIoutputCS(0);
+    SPIwrite24bits(command_regAddress, regValue);
+    SPIoutputCS(1);
+}
+
+//----------------------------------------
+// CMD_0001_nnnn_0000_0000_0000_0000_LOADn
+//
+// Transfers data from the selected CODE register(s) to the selected DAC register(s).
+//
+// @param[in] channel_0_3 = DAC Selection: 0=OUTA, 1=OUTB, 2=OUTC, 3=OUTD, 4..15=ALL OUTA,OUTB,OUTC,OUTD
+void MAX5715::LOADn(uint8_t channel_0_3)
+{
+    
+    //----------------------------------------
+    // update channel selection from channel_0_3
+    channelNumber_0_3 = channel_0_3;
+    switch (channelNumber_0_3) {
+      case 0: 
+        channels_bitmask_DCBA = 0x01; // OUTA only
+        break;
+      case 1: 
+        channels_bitmask_DCBA = 0x02; // OUTB only
+        break;
+      case 2: 
+        channels_bitmask_DCBA = 0x04; // OUTC only
+        break;
+      case 3: 
+        channels_bitmask_DCBA = 0x08; // OUTD only
+        break;
+      default: 
+        channels_bitmask_DCBA = 0x0F; // ALL OUTA,OUTB,OUTC,OUTD
+    }
+    
+    //----------------------------------------
+    // Define command code
+    uint8_t command_regAddress = CMD_0001_nnnn_0000_0000_0000_0000_LOADn | (channel_0_3 & 0x0F);
+    uint16_t regValue = (0 << 4); // left-align dddd_dddd_dddd_0000
+    
+    //----------------------------------------
+    // SPI write 8-bit regAddress and 16-bit regValue
+    // int16_t mosiData16 = ((command_regAddress << 8) & 0xFF00) | ((regValue >> 8) & 0xFF);
+    // int8_t mosiData8_0000FF = (regValue & 0xFF);
+    SPIoutputCS(0);
+    SPIwrite24bits(command_regAddress, regValue);
+    SPIoutputCS(1);
+}
+
+//----------------------------------------
+// CMD_0100_0000_0000_dcba_0000_0000_POWERn_Normal
+//
+// Sets the power mode of the selected DACs
+// (DACs selected with a 1 in the corresponding DACn bit are updated,
+// DACs with a 0 in the corresponding DACn bit are not impacted)
+//
+// @param[in] channels_bitmask_DCBA = channel select bitmap
+//     bit 1000 = channel D
+//     bit 0100 = channel C
+//     bit 0010 = channel B
+//     bit 0001 = channel A
+// @param[in] powerValue = power configuration for selected channel
+void MAX5715::POWER(uint8_t channels_bitmask_DCBA, MAX5715_POWER_enum_t powerValue)
+{
+    
+    //----------------------------------------
+    // update channel selection from channels_bitmask_DCBA
+    channels_bitmask_DCBA = channels_bitmask_DCBA;
+    if (channels_bitmask_DCBA == 0x0F) {
+        channelNumber_0_3 = 0x0F; // ALL OUTA,OUTB,OUTC,OUTD
+    }
+    else if ((channels_bitmask_DCBA & 0x01) != 0) {
+        channelNumber_0_3 = 0x00; // OUTA only
+    }
+    else if ((channels_bitmask_DCBA & 0x02) != 0) {
+        channelNumber_0_3 = 0x01; // OUTB only
+    }
+    else if ((channels_bitmask_DCBA & 0x04) != 0) {
+        channelNumber_0_3 = 0x02; // OUTC only
+    }
+    else {
+        channelNumber_0_3 = 0x03; // OUTD only
+    }
+    
+    //----------------------------------------
+    // select command_regAddress based on condition
+    uint8_t command_regAddress = CMD_0100_0000_0000_dcba_0000_0000_POWERn_Normal; // diagnostic
+    uint16_t regValue = ((channels_bitmask_DCBA & 0x0F) << 8); // 0000_dcba_0000_0000
+    // select command_regAddress from list of 4 values, based on condition
+    if (powerValue == POWERn_PD100k) {
+        command_regAddress = CMD_0100_0010_0000_dcba_0000_0000_POWERn_PD100k;
+    }
+    if (powerValue == POWERn_PD1k) {
+        command_regAddress = CMD_0100_0001_0000_dcba_0000_0000_POWERn_PD1k;
+    }
+    if (powerValue == POWERn_Normal) {
+        command_regAddress = CMD_0100_0000_0000_dcba_0000_0000_POWERn_Normal;
+    }
+    if (powerValue == POWERn_PDHiZ) {
+        command_regAddress = CMD_0100_0011_0000_dcba_0000_0000_POWERn_PDHiZ;
+    }
+    
+    //----------------------------------------
+    // SPI write 8-bit regAddress and 16-bit regValue
+    // int16_t mosiData16 = ((command_regAddress << 8) & 0xFF00) | ((regValue >> 8) & 0xFF);
+    // int8_t mosiData8_0000FF = (regValue & 0xFF);
+    SPIoutputCS(0);
+    SPIwrite24bits(command_regAddress, regValue);
+    SPIoutputCS(1);
+}
+
+//----------------------------------------
+// CMD_0111_0000_0000_0000_0000_0000_REF_EXT
+// CMD_0111_0001_0000_0000_0000_0000_REF_2V500
+// CMD_0111_0010_0000_0000_0000_0000_REF_2V048
+// CMD_0111_0011_0000_0000_0000_0000_REF_4V096
+// CMD_0111_0100_0000_0000_0000_0000_REF_AlwaysOn_EXT
+// CMD_0111_0101_0000_0000_0000_0000_REF_AlwaysOn_2V500
+// CMD_0111_0110_0000_0000_0000_0000_REF_AlwaysOn_2V048
+// CMD_0111_0111_0000_0000_0000_0000_REF_AlwaysOn_4V096
+//
+// Sets the reference operating mode.
+// REF Power (B18): 0 = Internal reference is only powered if at least one DAC is powered
+// 1 = Internal reference is always powered
+void MAX5715::REF(MAX5715_REF_enum_t value)
+{
+    
+    //----------------------------------------
+    // select command_regAddress based on condition
+    uint8_t command_regAddress = CMD_0111_0110_0000_0000_0000_0000_REF_AlwaysOn_2V048; // diagnostic
+    uint16_t regValue = 0; // 0000_0000_0000_0000
+    // select command_regAddress from list of 8 values, based on condition
+    if (value == REF_4V096) {
+        command_regAddress = CMD_0111_0011_0000_0000_0000_0000_REF_4V096;
+        VRef = 4.096;
+    }
+    if (value == REF_AlwaysOn_2V500) {
+        command_regAddress = CMD_0111_0101_0000_0000_0000_0000_REF_AlwaysOn_2V500;
+        VRef = 2.500;
+    }
+    if (value == REF_EXT) {
+        command_regAddress = CMD_0111_0000_0000_0000_0000_0000_REF_EXT;
+    }
+    if (value == REF_AlwaysOn_EXT) {
+        command_regAddress = CMD_0111_0100_0000_0000_0000_0000_REF_AlwaysOn_EXT;
+    }
+    if (value == REF_2V500) {
+        command_regAddress = CMD_0111_0001_0000_0000_0000_0000_REF_2V500;
+        VRef = 2.500;
+    }
+    if (value == REF_AlwaysOn_2V048) {
+        command_regAddress = CMD_0111_0110_0000_0000_0000_0000_REF_AlwaysOn_2V048;
+        VRef = 2.048;
+    }
+    if (value == REF_AlwaysOn_4V096) {
+        command_regAddress = CMD_0111_0111_0000_0000_0000_0000_REF_AlwaysOn_4V096;
+        VRef = 4.096;
+    }
+    if (value == REF_2V048) {
+        command_regAddress = CMD_0111_0010_0000_0000_0000_0000_REF_2V048;
+        VRef = 2.048;
+    }
+    
+    //----------------------------------------
+    // SPI write 8-bit regAddress and 16-bit regValue
+    // int16_t mosiData16 = ((command_regAddress << 8) & 0xFF00) | ((regValue >> 8) & 0xFF);
+    // int8_t mosiData8_0000FF = (regValue & 0xFF);
+    SPIoutputCS(0);
+    SPIwrite24bits(command_regAddress, regValue);
+    SPIoutputCS(1);
+    
+    //----------------------------------------
+    // shadow of write-only register REF CMD_0111_0rrr
+    Shadow_0111_0rrr_REF = regValue;
+}
+
+//----------------------------------------
+// CMD_0101_0000_0000_0000_0000_0000_SW_CLEAR
+//
+// Software Clear
+// All CODE and DAC registers cleared to their default values.
+//
+// @return 1 on success; 0 on failure
+uint8_t MAX5715::SW_CLEAR(void)
+{
+    
+    //----------------------------------------
+    // Define command code
+    uint8_t command_regAddress = CMD_0101_0000_0000_0000_0000_0000_SW_CLEAR;
+    uint16_t regValue = 0; // 0000_0000_0000_0000
+    
+    //----------------------------------------
+    // SPI write 8-bit regAddress and 16-bit regValue
+    // int16_t mosiData16 = ((command_regAddress << 8) & 0xFF00) | ((regValue >> 8) & 0xFF);
+    // int8_t mosiData8_0000FF = (regValue & 0xFF);
+    SPIoutputCS(0);
+    SPIwrite24bits(command_regAddress, regValue);
+    SPIoutputCS(1);
+    
+    //----------------------------------------
+    // after successful SW_RESET, update shadow registers
+    // assume SPI write was successful
+    if (1)
+    {
+      // shadow of write-only register CODE[channel_0_3] CMD_0010_nnnn
+      Shadow_0010_nnnn_CODE[0] = 0x0000;
+      Shadow_0010_nnnn_CODE[1] = 0x0000;
+      Shadow_0010_nnnn_CODE[2] = 0x0000;
+      Shadow_0010_nnnn_CODE[3] = 0x0000;
+      //
+      // shadow of write-only register POWER[channel_0_3] CMD_0100_00pp
+      //Shadow_0100_00pp_POWER[0] = POWERn_Normal;
+      //Shadow_0100_00pp_POWER[1] = POWERn_Normal;
+      //Shadow_0100_00pp_POWER[2] = POWERn_Normal;
+      //Shadow_0100_00pp_POWER[3] = POWERn_Normal;
+      //
+      // shadow of write-only register CONFIG[channel_0_3] CMD_0110_a00t
+      //Shadow_0110_a00t_CONFIG[0] = 0; // normal (latched, not transparent)
+      //Shadow_0110_a00t_CONFIG[1] = 0; // normal (latched, not transparent)
+      //Shadow_0110_a00t_CONFIG[2] = 0; // normal (latched, not transparent)
+      //Shadow_0110_a00t_CONFIG[3] = 0; // normal (latched, not transparent)
+      //
+      // shadow of write-only register REF CMD_0111_0rrr
+      //Shadow_0111_0rrr_REF = REF_EXT;
+      //
+      // shadow of CODE field of write-only register CODE[channel_0_3] CMD_0010_nnnn
+      CODE[0] = 0x0000;
+      CODE[1] = 0x0000;
+      CODE[2] = 0x0000;
+      CODE[3] = 0x0000;
+      //
+    }
+    
+    //----------------------------------------
+    // success
+    return 1;
+}
+
+//----------------------------------------
+// CMD_0101_0001_0000_0000_0000_0000_SW_RESET
+//
+// Software Reset
+// All CODE, DAC, and control registers returned to their default values,
+// simulating a power cycle reset.
+//
+// @return 1 on success; 0 on failure
+uint8_t MAX5715::SW_RESET(void)
+{
+    
+    //----------------------------------------
+    // Define command code
+    uint8_t command_regAddress = CMD_0101_0001_0000_0000_0000_0000_SW_RESET;
+    uint16_t regValue = 0; // 0000_0000_0000_0000
+    
+    //----------------------------------------
+    // SPI write 8-bit regAddress and 16-bit regValue
+    // int16_t mosiData16 = ((command_regAddress << 8) & 0xFF00) | ((regValue >> 8) & 0xFF);
+    // int8_t mosiData8_0000FF = (regValue & 0xFF);
+    SPIoutputCS(0);
+    SPIwrite24bits(command_regAddress, regValue);
+    SPIoutputCS(1);
+    
+    //----------------------------------------
+    // after successful SW_RESET, update shadow registers
+    // assume SPI write was successful
+    if (1)
+    {
+      // shadow of write-only register CODE[channel_0_3] CMD_0010_nnnn
+      Shadow_0010_nnnn_CODE[0] = 0x0000;
+      Shadow_0010_nnnn_CODE[1] = 0x0000;
+      Shadow_0010_nnnn_CODE[2] = 0x0000;
+      Shadow_0010_nnnn_CODE[3] = 0x0000;
+      //
+      // shadow of write-only register POWER[channel_0_3] CMD_0100_00pp
+      Shadow_0100_00pp_POWER[0] = POWERn_Normal;
+      Shadow_0100_00pp_POWER[1] = POWERn_Normal;
+      Shadow_0100_00pp_POWER[2] = POWERn_Normal;
+      Shadow_0100_00pp_POWER[3] = POWERn_Normal;
+      //
+      // shadow of write-only register CONFIG[channel_0_3] CMD_0110_a00t
+      Shadow_0110_a00t_CONFIG[0] = 0; // normal (latched, not transparent)
+      Shadow_0110_a00t_CONFIG[1] = 0; // normal (latched, not transparent)
+      Shadow_0110_a00t_CONFIG[2] = 0; // normal (latched, not transparent)
+      Shadow_0110_a00t_CONFIG[3] = 0; // normal (latched, not transparent)
+      //
+      // shadow of write-only register REF CMD_0111_0rrr
+      Shadow_0111_0rrr_REF = REF_EXT;
+      //
+      // shadow of CODE field of write-only register CODE[channel_0_3] CMD_0010_nnnn
+      CODE[0] = 0x0000;
+      CODE[1] = 0x0000;
+      CODE[2] = 0x0000;
+      CODE[3] = 0x0000;
+      //
+    }
+    
+    //----------------------------------------
+    // success
+    return 1;
+}
+
+
+// End of file