Maxim Integrated MAX5171 14-bit Force/Sense DAC
Dependents: MAX5171BOB_Tester MAX5171BOB_14bit_Remote_Sense_SPI_DAC MAX5171BOB_Serial_Tester
Diff: MAX5171.cpp
- Revision:
- 1:e73245718b2a
- Parent:
- 0:80a9add62408
- Child:
- 3:79839617d532
--- a/MAX5171.cpp Fri May 31 21:50:12 2019 +0000 +++ b/MAX5171.cpp Fri Jun 07 21:53:56 2019 +0000 @@ -1,570 +1,563 @@ -// /******************************************************************************* -// * 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 MAX5171.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 "MAX5171.h" - -// Device Name = MAX5171 -// Device Description = Low-Power, Serial, 14-Bit, 1-Channel DACs with Force/Sense Voltage Output and SPI Interface -// Device Manufacturer = Maxim Integrated -// Device PartNumber = MAX5171AEEE+ -// Device RegValue_Width = DataWidth16bit_HL -// -// DAC NumChannels = 1 -// DAC ResolutionBits = 14 -// -// SPI CS = ActiveLow -// SPI FrameStart = CS -// SPI CPOL = 0 -// SPI CPHA = 0 -// SPI MOSI and MISO Data are both stable on Rising edge of SCLK -// SPI SCLK Idle Low -// SPI SCLKMaxMHz = 10 -// SPI SCLKMinMHz = 0 -// -// InputPin Name = FB -// InputPin Description = Feedback Input -// InputPin Function = Analog -// -// InputPin Name = RS -// InputPin Description = Reset Mode Select (digital input). Connect to VDD to select midscale reset output value. Connect to DGND -// to select 0 reset output value. -// InputPin Function = Configuration -// -// InputPin Name = PDL# -// InputPin Description = Power-Down Lockout (digital input). Connect to VDD to allow shutdown. Connect to DGND to disable shutdown. -// InputPin Function = Configuration -// -// InputPin Name = CLR# -// InputPin Description = Clear DAC (digital input). Clears the DAC to its predetermined output state as set by RS. -// InputPin Function = Configuration -// -// InputPin Name = SHDN -// InputPin Description = Shutdown (digital input). Pulling SHDN high when PDL = VDD places the chip in shutdown mode with a -// maximum shutdown current 0f 10uA. -// InputPin Function = Configuration -// -// OutputPin Name = OUT -// OutputPin Description = Analog Voltage Output. High impedance in shutdown. Output voltage is limited to VDD. -// OutputPin Function = Analog -// -// OutputPin Name = UPO -// OutputPin Description = User-Programmable Output. State is set by serial input. -// OutputPin Function = General-Purpose -// -// SupplyPin Name = VDD -// SupplyPin Description = Positive Supply. Bypass to AGND with a 4.7uF capacitor in parallel with a 0.1uF capacitor. -// SupplyPin VinMax = 4.50 -// SupplyPin VinMin = 5.50 -// SupplyPin Function = Analog -// -// SupplyPin Name = REF -// SupplyPin Description = Reference Input. Maximum VREF is VDD - 1.4V. Connect an external +2.5V reference. -// SupplyPin VinMax = VDD-1.4 -// SupplyPin VinMin = 0 -// SupplyPin Function = Analog -// -// SupplyPin Name = DGND -// SupplyPin Description = Digital Ground. -// SupplyPin VinMax = 0 -// SupplyPin VinMin = 0 -// SupplyPin Function = Analog -// -// SupplyPin Name = AGND -// SupplyPin Description = Analog Ground. -// SupplyPin VinMax = 0 -// SupplyPin VinMin = 0 -// SupplyPin Function = Analog -// - -// CODE GENERATOR: class constructor definition -MAX5171::MAX5171(SPI &spi, DigitalOut &cs_pin, // SPI interface - // CODE GENERATOR: class constructor definition gpio InputPin pins - // AnalogOut &FB_pin, // Analog Input to MAX5171 device - DigitalOut &RS_pin, // Digital Configuration Input to MAX5171 device - DigitalOut &PDLb_pin, // Digital Configuration Input to MAX5171 device - DigitalOut &CLRb_pin, // Digital Configuration Input to MAX5171 device - DigitalOut &SHDN_pin, // Digital Configuration Input to MAX5171 device - // CODE GENERATOR: class constructor definition gpio OutputPin pins - // AnalogIn &OUT_pin, // Analog Output from MAX5171 device - DigitalIn &UPO_pin, // Digital General-Purpose Output from MAX5171 device - // CODE GENERATOR: class constructor definition ic_variant - MAX5171_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_FB_pin(FB_pin), // Analog Input to MAX5171 device - m_RS_pin(RS_pin), // Digital Configuration Input to MAX5171 device - m_PDLb_pin(PDLb_pin), // Digital Configuration Input to MAX5171 device - m_CLRb_pin(CLRb_pin), // Digital Configuration Input to MAX5171 device - m_SHDN_pin(SHDN_pin), // Digital Configuration Input to MAX5171 device - // CODE GENERATOR: class constructor initializer list gpio OutputPin pins - // m_OUT_pin(OUT_pin), // Analog Output from MAX5171 device - m_UPO_pin(UPO_pin), // Digital General-Purpose Output from MAX5171 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 = 0 - // SPI CPHA = 0 - // SPI MOSI and MISO Data are both stable on Rising edge of SCLK - // SPI SCLK Idle Low - m_SPI_dataMode = 0; //SPI_MODE0 // CPOL=0,CPHA=0: Rising Edge stable; SCLK idle Low - m_spi.format(8,m_SPI_dataMode); // int bits_must_be_8, int mode=0_3 CPOL=0,CPHA=0 - - // SPI SCLKMaxMHz = 10 - // 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 = 10000000; // 10MHz; MAX5171 limit is 10MHz - m_spi.frequency(m_SPI_SCLK_Hz); - - // TODO1: CODE GENERATOR: class constructor definition gpio InputPin (Input to device) initialization - // - m_RS_pin = 1; // output logic high -- initial value in constructor - m_PDLb_pin = 1; // output logic high -- initial value in constructor - m_CLRb_pin = 1; // output logic high -- initial value in constructor - m_SHDN_pin = 1; // output logic high -- initial value in constructor -} - -// CODE GENERATOR: class destructor definition -MAX5171::~MAX5171() -{ - // do nothing -} - -// CODE GENERATOR: spi_frequency setter definition -// set SPI SCLK frequency -void MAX5171::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_MAX5171_device -// CODE GENERATOR: extern function declarations -// CODE GENERATOR: extern function requirement MAX5171::SPIoutputCS -// Assert SPI Chip Select -// SPI chip-select for MAX5171 -// -void MAX5171::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 MAX5171::SPIwrite16bits -// SPI write 16 bits -// SPI interface to MAX5171 shift 16 bits mosiData into MAX5171 DIN -// -void MAX5171::SPIwrite16bits(int16_t mosiData16) -{ - // CODE GENERATOR: extern function definition for function SPIwrite16bits - // TODO1: CODE GENERATOR: extern function definition for standard SPI interface function SPIwrite16bits(int16_t mosiData16) - size_t byteCount = 2; - static char mosiData[2]; - static char misoData[2]; - mosiData[0] = (char)((mosiData16 >> 8) & 0xFF); // MSByte - mosiData[1] = (char)((mosiData16 >> 0) & 0xFF); // LSByte - // - // Arduino: begin critical section: noInterrupts() masks all interrupt sources; end critical section with interrupts() - //~ noInterrupts(); - // - //~ digitalWrite(Scope_Trigger_Pin, LOW); // diagnostic Scope_Trigger_Pin - // - unsigned int numBytesTransferred = m_spi.write(mosiData, byteCount, misoData, byteCount); - //~ m_spi.transfer(mosiData8_FF0000); - //~ m_spi.transfer(mosiData16_00FF00); - //~ m_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 0 // 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 0 // HAS_DAPLINK_SERIAL - cmdLine_DAPLINKserial.serial().printf("\r\nSPI"); - if (byteCount > 7) { - cmdLine_DAPLINKserial.serial().printf(" byteCount:%d", byteCount); - } - cmdLine_DAPLINKserial.serial().printf(" MOSI->"); - for (unsigned int byteIndex = 0; byteIndex < byteCount; byteIndex++) - { - cmdLine_DAPLINKserial.serial().printf(" 0x%2.2X", mosiData[byteIndex]); - } - // hex dump misoData[0..byteCount-1] - cmdLine_DAPLINKserial.serial().printf(" MISO<-"); - for (unsigned int byteIndex = 0; byteIndex < numBytesTransferred; byteIndex++) - { - cmdLine_DAPLINKserial.serial().printf(" 0x%2.2X", misoData[byteIndex]); - } - cmdLine_DAPLINKserial.serial().printf(" "); -#endif - // VERIFY: DIAGNOSTIC: print MAX5715 device register write - // TODO: MAX5715_print_register_verbose(mosiData8_FF0000, mosiData16_00FFFF); - // TODO: print_verbose_SPI_diagnostic(mosiData16_FF00, mosiData16_00FF, misoData16_FF00, misoData16_00FF); - // - // int misoData16 = (misoData16_FF00 << 8) | misoData16_00FF; - // return misoData16; -} - -// CODE GENERATOR: class member function definitions -//---------------------------------------- -// Initialize device -// @return 1 on success; 0 on failure -uint8_t MAX5171::Init(void) -{ - - //---------------------------------------- - // success - return 1; -} - -//---------------------------------------- -// 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 14-bit MAX5171 code (right justified). -uint16_t MAX5171::DACCodeOfVoltage(double voltageV) -{ - - //---------------------------------------- - // Linear map min and max endpoints - const double MaxScaleVoltage = VRef; // voltage of maximum code 0x3fff - const double MinScaleVoltage = 0.0; // voltage of minimum code 0x000 - const uint16_t FULL_SCALE_CODE_14BIT = 0x3fff; - const uint16_t MaxCode = FULL_SCALE_CODE_14BIT; - 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_u14: raw 14-bit MAX5171 code (right justified). -// @return physical voltage corresponding to MAX5171 code. -double MAX5171::VoltageOfCode(uint16_t value_u14) -{ - - //---------------------------------------- - // Linear map min and max endpoints - double MaxScaleVoltage = VRef; // voltage of maximum code 0x3fff - double MinScaleVoltage = 0.0; // voltage of minimum code 0x000 - const uint16_t FULL_SCALE_CODE_14BIT = 0x3fff; - const uint16_t MaxCode = FULL_SCALE_CODE_14BIT; - const uint16_t MinCode = 0x000; - double codeFraction = ((double)value_u14 - MinCode) / (MaxCode - MinCode + 1); - return MinScaleVoltage + ((MaxScaleVoltage - MinScaleVoltage) * codeFraction); -} - -//---------------------------------------- -// CMD_00dd_dddd_dddd_dddd_CODE -// -// Load input register; DAC registers are unchanged. -// @return 1 on success; 0 on failure -uint8_t MAX5171::CODE(uint16_t dacCodeLsbs) -{ - - //---------------------------------------- - // Define command code - uint16_t mosiData16 = CMD_00dd_dddd_dddd_dddd_CODE - | ((0x3FFF & dacCodeLsbs) << 0); // left-align dddd_dddd_dddd - - //---------------------------------------- - // SPI write 16-bit mosiData16 - SPIoutputCS(0); - SPIwrite16bits(mosiData16); - SPIoutputCS(1); - - //---------------------------------------- - // shadow of write-only register CMD_00dd_dddd_dddd_dddd_CODE - DACCode = dacCodeLsbs; - - //---------------------------------------- - // success - return 1; -} - -//---------------------------------------- -// CMD_01dd_dddd_dddd_dddd_CODE_LOAD -// -// Load input register; DAC registers are updated (start up DAC with new data). -// @return 1 on success; 0 on failure -uint8_t MAX5171::CODE_LOAD(uint16_t dacCodeLsbs) -{ - - //---------------------------------------- - // Define command code - uint16_t mosiData16 = CMD_01dd_dddd_dddd_dddd_CODE_LOAD - | ((0x3FFF & dacCodeLsbs) << 0); // left-align dddd_dddd_dddd - - //---------------------------------------- - // SPI write 16-bit mosiData16 - SPIoutputCS(0); - SPIwrite16bits(mosiData16); - SPIoutputCS(1); - - //---------------------------------------- - // shadow of write-only register CMD_00dd_dddd_dddd_dddd_CODE - DACCode = dacCodeLsbs; - - //---------------------------------------- - // success - return 1; -} - -//---------------------------------------- -// CMD_10xx_xxxx_xxxx_xxxx_LOAD -// -// Update DAC register from input register (start up DAC with data previously -// stored in the input registers). -// @return 1 on success; 0 on failure -uint8_t MAX5171::LOAD(void) -{ - - //---------------------------------------- - // Define command code - uint16_t mosiData16 = CMD_10xx_xxxx_xxxx_xxxx_LOAD; - - //---------------------------------------- - // SPI write 16-bit mosiData16 - SPIoutputCS(0); - SPIwrite16bits(mosiData16); - SPIoutputCS(1); - - //---------------------------------------- - // success - return 1; -} - -//---------------------------------------- -// CMD_1100_xxxx_xxxx_xxxx_NOP -// -// No operation (NOP). -// @return 1 on success; 0 on failure -uint8_t MAX5171::NOP(void) -{ - - //---------------------------------------- - // Define command code - uint16_t mosiData16 = CMD_1100_xxxx_xxxx_xxxx_NOP; - - //---------------------------------------- - // SPI write 16-bit mosiData16 - SPIoutputCS(0); - SPIwrite16bits(mosiData16); - SPIoutputCS(1); - - //---------------------------------------- - // success - return 1; -} - -//---------------------------------------- -// CMD_1101_xxxx_xxxx_xxxx_SHUTDOWN -// -// Shut down DAC (provided PDL# = 1). -// @return 1 on success; 0 on failure -uint8_t MAX5171::SHUTDOWN(void) -{ - - //---------------------------------------- - // Define command code - uint16_t mosiData16 = CMD_1101_xxxx_xxxx_xxxx_SHUTDOWN; - - //---------------------------------------- - // SPI write 16-bit mosiData16 - SPIoutputCS(0); - SPIwrite16bits(mosiData16); - SPIoutputCS(1); - - //---------------------------------------- - // success - return 1; -} - -//---------------------------------------- -// CMD_1110_0xxx_xxxx_xxxx_UPO_LOW -// -// UPO goes low (default). -// @return 1 on success; 0 on failure -uint8_t MAX5171::UPO_LOW(void) -{ - - //---------------------------------------- - // Define command code - uint16_t mosiData16 = CMD_1110_0xxx_xxxx_xxxx_UPO_LOW; - - //---------------------------------------- - // SPI write 16-bit mosiData16 - SPIoutputCS(0); - SPIwrite16bits(mosiData16); - SPIoutputCS(1); - - //---------------------------------------- - // success - return 1; -} - -//---------------------------------------- -// CMD_1110_1xxx_xxxx_xxxx_UPO_HIGH -// -// UPO goes high. -// @return 1 on success; 0 on failure -uint8_t MAX5171::UPO_HIGH(void) -{ - - //---------------------------------------- - // Define command code - uint16_t mosiData16 = CMD_1110_1xxx_xxxx_xxxx_UPO_HIGH; - - //---------------------------------------- - // SPI write 16-bit mosiData16 - SPIoutputCS(0); - SPIwrite16bits(mosiData16); - SPIoutputCS(1); - - //---------------------------------------- - // success - return 1; -} - -//---------------------------------------- -// CMD_1111_0xxx_xxxx_xxxx_MODE1_DOUT_SCLK_RISING_EDGE -// -// Mode 1, DOUT clocked out on SCLK’s rising edge. -// @return 1 on success; 0 on failure -uint8_t MAX5171::MODE1_DOUT_SCLK_RISING_EDGE(void) -{ - - //---------------------------------------- - // Define command code - uint16_t mosiData16 = CMD_1111_0xxx_xxxx_xxxx_MODE1_DOUT_SCLK_RISING_EDGE; - - //---------------------------------------- - // SPI write 16-bit mosiData16 - SPIoutputCS(0); - SPIwrite16bits(mosiData16); - SPIoutputCS(1); - - //---------------------------------------- - // success - return 1; -} - -//---------------------------------------- -// CMD_1111_1xxx_xxxx_xxxx_MODE0_DOUT_SCLK_FALLING_EDGE -// -// Mode 0, DOUT clocked out on SCLK’s falling edge (default). -// @return 1 on success; 0 on failure -uint8_t MAX5171::MODE0_DOUT_SCLK_FALLING_EDGE(void) -{ - - //---------------------------------------- - // Define command code - uint16_t mosiData16 = CMD_1111_1xxx_xxxx_xxxx_MODE0_DOUT_SCLK_FALLING_EDGE; - - //---------------------------------------- - // SPI write 16-bit mosiData16 - SPIoutputCS(0); - SPIwrite16bits(mosiData16); - SPIoutputCS(1); - - //---------------------------------------- - // success - return 1; -} - - -// End of file +// /******************************************************************************* +// * 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 MAX5171.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 "MAX5171.h" + +// Device Name = MAX5171 +// Device Description = Low-Power, Serial, 14-Bit, 1-Channel DACs with Force/Sense Voltage Output and SPI Interface +// Device Manufacturer = Maxim Integrated +// Device PartNumber = MAX5171AEEE+ +// Device RegValue_Width = DataWidth16bit_HL +// +// DAC NumChannels = 1 +// DAC ResolutionBits = 14 +// +// SPI CS = ActiveLow +// SPI FrameStart = CS +// SPI CPOL = 0 +// SPI CPHA = 0 +// SPI MOSI and MISO Data are both stable on Rising edge of SCLK +// SPI SCLK Idle Low +// SPI SCLKMaxMHz = 10 +// SPI SCLKMinMHz = 0 +// +// InputPin Name = FB +// InputPin Description = Feedback Input +// InputPin Function = Analog +// +// InputPin Name = RS +// InputPin Description = Reset Mode Select (digital input). Connect to VDD to select midscale reset output value. Connect to DGND +// to select 0 reset output value. +// InputPin Function = Configuration +// +// InputPin Name = PDL# +// InputPin Description = Power-Down Lockout (digital input). Connect to VDD to allow shutdown. Connect to DGND to disable shutdown. +// InputPin Function = Configuration +// +// InputPin Name = CLR# +// InputPin Description = Clear DAC (digital input). Clears the DAC to its predetermined output state as set by RS. +// InputPin Function = Configuration +// +// InputPin Name = SHDN +// InputPin Description = Shutdown (digital input). Pulling SHDN high when PDL = VDD places the chip in shutdown mode with a +// maximum shutdown current 0f 10uA. +// InputPin Function = Configuration +// +// OutputPin Name = OUT +// OutputPin Description = Analog Voltage Output. High impedance in shutdown. Output voltage is limited to VDD. +// OutputPin Function = Analog +// +// OutputPin Name = UPO +// OutputPin Description = User-Programmable Output. State is set by serial input. +// OutputPin Function = General-Purpose +// +// SupplyPin Name = VDD +// SupplyPin Description = Positive Supply. Bypass to AGND with a 4.7uF capacitor in parallel with a 0.1uF capacitor. +// SupplyPin VinMax = 4.50 +// SupplyPin VinMin = 5.50 +// SupplyPin Function = Analog +// +// SupplyPin Name = REF +// SupplyPin Description = Reference Input. Maximum VREF is VDD - 1.4V. Connect an external +2.5V reference. +// SupplyPin VinMax = VDD-1.4 +// SupplyPin VinMin = 0 +// SupplyPin Function = Analog +// +// SupplyPin Name = DGND +// SupplyPin Description = Digital Ground. +// SupplyPin VinMax = 0 +// SupplyPin VinMin = 0 +// SupplyPin Function = Analog +// +// SupplyPin Name = AGND +// SupplyPin Description = Analog Ground. +// SupplyPin VinMax = 0 +// SupplyPin VinMin = 0 +// SupplyPin Function = Analog +// + +// CODE GENERATOR: class constructor definition +MAX5171::MAX5171(SPI &spi, DigitalOut &cs_pin, // SPI interface + // CODE GENERATOR: class constructor definition gpio InputPin pins + // AnalogOut &FB_pin, // Analog Input to MAX5171 device + DigitalOut &RS_pin, // Digital Configuration Input to MAX5171 device + DigitalOut &PDLb_pin, // Digital Configuration Input to MAX5171 device + DigitalOut &CLRb_pin, // Digital Configuration Input to MAX5171 device + DigitalOut &SHDN_pin, // Digital Configuration Input to MAX5171 device + // CODE GENERATOR: class constructor definition gpio OutputPin pins + // AnalogIn &OUT_pin, // Analog Output from MAX5171 device + DigitalIn &UPO_pin, // Digital General-Purpose Output from MAX5171 device + // CODE GENERATOR: class constructor definition ic_variant + MAX5171_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_FB_pin(FB_pin), // Analog Input to MAX5171 device + m_RS_pin(RS_pin), // Digital Configuration Input to MAX5171 device + m_PDLb_pin(PDLb_pin), // Digital Configuration Input to MAX5171 device + m_CLRb_pin(CLRb_pin), // Digital Configuration Input to MAX5171 device + m_SHDN_pin(SHDN_pin), // Digital Configuration Input to MAX5171 device + // CODE GENERATOR: class constructor initializer list gpio OutputPin pins + // m_OUT_pin(OUT_pin), // Analog Output from MAX5171 device + m_UPO_pin(UPO_pin), // Digital General-Purpose Output from MAX5171 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 = 0 + // SPI CPHA = 0 + // SPI MOSI and MISO Data are both stable on Rising edge of SCLK + // SPI SCLK Idle Low + m_SPI_dataMode = 0; //SPI_MODE0 // CPOL=0,CPHA=0: Rising Edge stable; SCLK idle Low + m_spi.format(8,m_SPI_dataMode); // int bits_must_be_8, int mode=0_3 CPOL=0,CPHA=0 + + // SPI SCLKMaxMHz = 10 + // 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 = 10000000; // 10MHz; MAX5171 limit is 10MHz + m_spi.frequency(m_SPI_SCLK_Hz); + + // TODO1: CODE GENERATOR: class constructor definition gpio InputPin (Input to device) initialization + // + m_RS_pin = 1; // output logic high -- initial value in constructor + m_PDLb_pin = 1; // output logic high -- initial value in constructor + m_CLRb_pin = 1; // output logic high -- initial value in constructor + m_SHDN_pin = 1; // output logic high -- initial value in constructor +} + +// CODE GENERATOR: class destructor definition +MAX5171::~MAX5171() +{ + // do nothing +} + +// CODE GENERATOR: spi_frequency setter definition +// set SPI SCLK frequency +void MAX5171::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_MAX5171_device +// CODE GENERATOR: extern function declarations +// CODE GENERATOR: extern function requirement MAX5171::SPIoutputCS +// Assert SPI Chip Select +// SPI chip-select for MAX5171 +// +void MAX5171::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 MAX5171::SPIwrite16bits +// SPI write 16 bits +// SPI interface to MAX5171 shift 16 bits mosiData into MAX5171 DIN +// +void MAX5171::SPIwrite16bits(int16_t mosiData16) +{ + // CODE GENERATOR: extern function definition for function SPIwrite16bits + // TODO1: CODE GENERATOR: extern function definition for standard SPI interface function SPIwrite16bits(int16_t mosiData16) + size_t byteCount = 2; + static char mosiData[2]; + static char misoData[2]; + mosiData[0] = (char)((mosiData16 >> 8) & 0xFF); // MSByte + mosiData[1] = (char)((mosiData16 >> 0) & 0xFF); // LSByte + // + // Arduino: begin critical section: noInterrupts() masks all interrupt sources; end critical section with interrupts() + //~ noInterrupts(); + // + //~ digitalWrite(Scope_Trigger_Pin, LOW); // diagnostic Scope_Trigger_Pin + // + unsigned int numBytesTransferred = m_spi.write(mosiData, byteCount, misoData, byteCount); + //~ m_spi.transfer(mosiData8_FF0000); + //~ m_spi.transfer(mosiData16_00FF00); + //~ m_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 0 // 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 0 // HAS_DAPLINK_SERIAL + cmdLine_DAPLINKserial.serial().printf("\r\nSPI"); + if (byteCount > 7) { + cmdLine_DAPLINKserial.serial().printf(" byteCount:%d", byteCount); + } + cmdLine_DAPLINKserial.serial().printf(" MOSI->"); + for (unsigned int byteIndex = 0; byteIndex < byteCount; byteIndex++) { + cmdLine_DAPLINKserial.serial().printf(" 0x%2.2X", mosiData[byteIndex]); + } + // hex dump misoData[0..byteCount-1] + cmdLine_DAPLINKserial.serial().printf(" MISO<-"); + for (unsigned int byteIndex = 0; byteIndex < numBytesTransferred; byteIndex++) { + cmdLine_DAPLINKserial.serial().printf(" 0x%2.2X", misoData[byteIndex]); + } + cmdLine_DAPLINKserial.serial().printf(" "); +#endif + // VERIFY: DIAGNOSTIC: print MAX5715 device register write + // TODO: MAX5715_print_register_verbose(mosiData8_FF0000, mosiData16_00FFFF); + // TODO: print_verbose_SPI_diagnostic(mosiData16_FF00, mosiData16_00FF, misoData16_FF00, misoData16_00FF); + // + // int misoData16 = (misoData16_FF00 << 8) | misoData16_00FF; + // return misoData16; +} +// CODE GENERATOR: class member function definitions +//---------------------------------------- +// Initialize device +// @return 1 on success; 0 on failure +uint8_t MAX5171::Init(void) +{ + + //---------------------------------------- + // success + return 1; +} + +//---------------------------------------- +// 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 14-bit MAX5171 code (right justified). +uint16_t MAX5171::DACCodeOfVoltage(double voltageV) +{ + + //---------------------------------------- + // Linear map min and max endpoints + const double MaxScaleVoltage = VRef; // voltage of maximum code 0x3fff + const double MinScaleVoltage = 0.0; // voltage of minimum code 0x000 + const uint16_t FULL_SCALE_CODE_14BIT = 0x3fff; + const uint16_t MaxCode = FULL_SCALE_CODE_14BIT; + 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_u14: raw 14-bit MAX5171 code (right justified). +// @return physical voltage corresponding to MAX5171 code. +double MAX5171::VoltageOfCode(uint16_t value_u14) +{ + + //---------------------------------------- + // Linear map min and max endpoints + double MaxScaleVoltage = VRef; // voltage of maximum code 0x3fff + double MinScaleVoltage = 0.0; // voltage of minimum code 0x000 + const uint16_t FULL_SCALE_CODE_14BIT = 0x3fff; + const uint16_t MaxCode = FULL_SCALE_CODE_14BIT; + const uint16_t MinCode = 0x000; + double codeFraction = ((double)value_u14 - MinCode) / (MaxCode - MinCode + 1); + return MinScaleVoltage + ((MaxScaleVoltage - MinScaleVoltage) * codeFraction); +} + +//---------------------------------------- +// CMD_00dd_dddd_dddd_dddd_CODE +// +// Load input register; DAC registers are unchanged. +// @return 1 on success; 0 on failure +uint8_t MAX5171::CODE(uint16_t dacCodeLsbs) +{ + + //---------------------------------------- + // Define command code + uint16_t mosiData16 = CMD_00dd_dddd_dddd_dddd_CODE + | ((0x3FFF & dacCodeLsbs) << 0); // left-align dddd_dddd_dddd + + //---------------------------------------- + // SPI write 16-bit mosiData16 + SPIoutputCS(0); + SPIwrite16bits(mosiData16); + SPIoutputCS(1); + + //---------------------------------------- + // shadow of write-only register CMD_00dd_dddd_dddd_dddd_CODE + DACCode = dacCodeLsbs; + + //---------------------------------------- + // success + return 1; +} + +//---------------------------------------- +// CMD_01dd_dddd_dddd_dddd_CODE_LOAD +// +// Load input register; DAC registers are updated (start up DAC with new data). +// @return 1 on success; 0 on failure +uint8_t MAX5171::CODE_LOAD(uint16_t dacCodeLsbs) +{ + + //---------------------------------------- + // Define command code + uint16_t mosiData16 = CMD_01dd_dddd_dddd_dddd_CODE_LOAD + | ((0x3FFF & dacCodeLsbs) << 0); // left-align dddd_dddd_dddd + + //---------------------------------------- + // SPI write 16-bit mosiData16 + SPIoutputCS(0); + SPIwrite16bits(mosiData16); + SPIoutputCS(1); + + //---------------------------------------- + // shadow of write-only register CMD_00dd_dddd_dddd_dddd_CODE + DACCode = dacCodeLsbs; + + //---------------------------------------- + // success + return 1; +} + +//---------------------------------------- +// CMD_10xx_xxxx_xxxx_xxxx_LOAD +// +// Update DAC register from input register (start up DAC with data previously +// stored in the input registers). +// @return 1 on success; 0 on failure +uint8_t MAX5171::LOAD(void) +{ + + //---------------------------------------- + // Define command code + uint16_t mosiData16 = CMD_10xx_xxxx_xxxx_xxxx_LOAD; + + //---------------------------------------- + // SPI write 16-bit mosiData16 + SPIoutputCS(0); + SPIwrite16bits(mosiData16); + SPIoutputCS(1); + + //---------------------------------------- + // success + return 1; +} + +//---------------------------------------- +// CMD_1100_xxxx_xxxx_xxxx_NOP +// +// No operation (NOP). +// @return 1 on success; 0 on failure +uint8_t MAX5171::NOP(void) +{ + + //---------------------------------------- + // Define command code + uint16_t mosiData16 = CMD_1100_xxxx_xxxx_xxxx_NOP; + + //---------------------------------------- + // SPI write 16-bit mosiData16 + SPIoutputCS(0); + SPIwrite16bits(mosiData16); + SPIoutputCS(1); + + //---------------------------------------- + // success + return 1; +} + +//---------------------------------------- +// CMD_1101_xxxx_xxxx_xxxx_SHUTDOWN +// +// Shut down DAC (provided PDL# = 1). +// @return 1 on success; 0 on failure +uint8_t MAX5171::SHUTDOWN(void) +{ + + //---------------------------------------- + // Define command code + uint16_t mosiData16 = CMD_1101_xxxx_xxxx_xxxx_SHUTDOWN; + + //---------------------------------------- + // SPI write 16-bit mosiData16 + SPIoutputCS(0); + SPIwrite16bits(mosiData16); + SPIoutputCS(1); + + //---------------------------------------- + // success + return 1; +} + +//---------------------------------------- +// CMD_1110_0xxx_xxxx_xxxx_UPO_LOW +// +// UPO goes low (default). +// @return 1 on success; 0 on failure +uint8_t MAX5171::UPO_LOW(void) +{ + + //---------------------------------------- + // Define command code + uint16_t mosiData16 = CMD_1110_0xxx_xxxx_xxxx_UPO_LOW; + + //---------------------------------------- + // SPI write 16-bit mosiData16 + SPIoutputCS(0); + SPIwrite16bits(mosiData16); + SPIoutputCS(1); + + //---------------------------------------- + // success + return 1; +} + +//---------------------------------------- +// CMD_1110_1xxx_xxxx_xxxx_UPO_HIGH +// +// UPO goes high. +// @return 1 on success; 0 on failure +uint8_t MAX5171::UPO_HIGH(void) +{ + + //---------------------------------------- + // Define command code + uint16_t mosiData16 = CMD_1110_1xxx_xxxx_xxxx_UPO_HIGH; + + //---------------------------------------- + // SPI write 16-bit mosiData16 + SPIoutputCS(0); + SPIwrite16bits(mosiData16); + SPIoutputCS(1); + + //---------------------------------------- + // success + return 1; +} + +//---------------------------------------- +// CMD_1111_0xxx_xxxx_xxxx_MODE1_DOUT_SCLK_RISING_EDGE +// +// Mode 1, DOUT clocked out on SCLK’s rising edge. +// @return 1 on success; 0 on failure +uint8_t MAX5171::MODE1_DOUT_SCLK_RISING_EDGE(void) +{ + + //---------------------------------------- + // Define command code + uint16_t mosiData16 = CMD_1111_0xxx_xxxx_xxxx_MODE1_DOUT_SCLK_RISING_EDGE; + + //---------------------------------------- + // SPI write 16-bit mosiData16 + SPIoutputCS(0); + SPIwrite16bits(mosiData16); + SPIoutputCS(1); + + //---------------------------------------- + // success + return 1; +} + +//---------------------------------------- +// CMD_1111_1xxx_xxxx_xxxx_MODE0_DOUT_SCLK_FALLING_EDGE +// +// Mode 0, DOUT clocked out on SCLK’s falling edge (default). +// @return 1 on success; 0 on failure +uint8_t MAX5171::MODE0_DOUT_SCLK_FALLING_EDGE(void) +{ + + //---------------------------------------- + // Define command code + uint16_t mosiData16 = CMD_1111_1xxx_xxxx_xxxx_MODE0_DOUT_SCLK_FALLING_EDGE; + + //---------------------------------------- + // SPI write 16-bit mosiData16 + SPIoutputCS(0); + SPIwrite16bits(mosiData16); + SPIoutputCS(1); + + //---------------------------------------- + // success + return 1; +} + + +// End of file