LTM9100 - Anyside™ High Voltage Isolated Switch Controller with I²C Command and Telemetry

Features

  • UL-CSA Recognition Pending: 5kVRMS for One Minute
  • Reinforced Insulation
  • Integrated Isolated Power Supply
  • Adjustable Turn-On Ramp Rate and Current Limit
  • I2C/SMBus Interface
  • 10-Bit ADC Monitors Current and Two Uncommitted Channels
  • High Common Mode Transient Immunity: ≥ 30kV/μs
  • Fault Status Alert and Power Good Outputs
  • Independent 3V to 5.5V Logic Supply
  • ±20kV ESD Across the Isolation Barrier
  • Maximum Continuous Working Voltage: 690VRMS
  • 14.6mm Creepage Distance
  • Low Current Shutdown Mode (<10μA)
  • 22mm × 9mm × 5.16mm BGA Package

Typical Application

LTM9100 Typical Application
LTM9100 Typical Application

Description

The LTM®9100 μModule® (micromodule) controller is a complete, galvanically isolated switch controller with I2C interface, for use as a load switch or hot swap controller. The load is soft started and controlled by an external N-channel MOSFET switch. Overcurrent protection minimizes MOSFET stress during start-up, input step and output short-circuit conditions. Owing to the isolated, floating character of the switch, it is easily configured for use in high side, low side and floating applications.

A single 5V supply powers both sides of the switch controller through an integrated, isolated DC/DC converter. A separate logic supply input allows easy interfacing with logic levels from 3V to 5.5V, independent of the main supply. Isolated measurements of load current and two additional voltage inputs are made by a 10-bit ADC, and accessed via the I2C interface.

The logic and I2C interface is separated from the switch controller by a 5kVRMS isolation barrier, making the LTM9100 ideal for systems where the switch operates on buses up to 1000VDC, as well as for providing galvanic isolation in systems where a ground path is broken to allow large common mode voltage swings. Uninterrupted communication is guaranteed for common mode transients of up to 30kV/μs.

Packaging

For complete and up to date package information and drawings, please refer to our packaging page

Part Number Package Code Temp Package
Drawing
RoHS
LTM9100CY#PBF 22mm x 9mm x 5.16mm BGA BGA C 05-08-1973 Yes
LTM9100HY#PBF 22mm x 9mm x 5.16mm BGA BGA H 05-08-1973 Yes
LTM9100IY#PBF 22mm x 9mm x 5.16mm BGA BGA I 05-08-1973 Yes


LTM9100 Package Drawing

Order Info

  • Part numbers ending in PBF are lead free. Solder plated terminal finish (SnPb) versions are non-standard and special terms and conditions and pricing applies if available. Please contact LTC marketing for information.
  • Part numbers containing TR or TRM are shipped in tape and reel or 500 unit mini tape and reel, respectively
  • Please refer to our general ordering information or the product datasheet for more details

Package Variations and Pricing

Part Number Package Temp Price
(1-99)
Price
(1k)*
RoHS
LTM9100CY#PBF 22mm x 9mm x 5.16mm BGA C $27.79 $19.45 Yes
LTM9100HY#PBF 22mm x 9mm x 5.16mm BGA H $33.57 $23.50 Yes
LTM9100IY#PBF 22mm x 9mm x 5.16mm BGA I $30.56 $21.40 Yes
Buy NowRequest Samples
* The USA list pricing shown is for BUDGETARY USE ONLY, shown in United States dollars (FOB USA per unit for the stated volume), and is subject to change. International prices may differ due to local duties, taxes, fees and exchange rates. For volume-specific price or delivery quotes, please contact your local Linear Technology sales office or authorized distributor.

Demo Boards

Linear Technology offers many demo boards free of charge to qualified customers. Contact your local sales office or distributor to inquire about a demo board. Certain demo boards are also available for sale via credit card on this website. Demo boards are for evaluation purposes only. It remains the customer’s responsibility to verify proper and reliable operation in the actual end application.

Part Number Description Price Documentation
DC2423A-A LTM9100 Demo Board | Isolated 48V Switch Controller with Telemetry [requires DC590 or DC2026] $150.00
DC2423A-B LTM9100 Demo Board | Isolated 380V Switch Controller with Telemetry [requires DC590 or DC2026] $150.00
Buy Now

Companion Boards

Part Number Description Price Documentation
DC2026C Linduino One Isolated USB Demo Board: An Arduino- and QuikEval-Compatible Code Development Platform $75.00
DC590B Isolated USB Serial Controller for Linear Technology QuikEval-Compatible Demo Boards $50.00
Buy Now
Click here to view our complete list of demo boards

Applications

  • High Voltage DC Hot Swap
  • Live Backplane Insertion
  • Isolated Distributed Power Systems
  • Power Monitors
  • Industrial Control Systems
  • Breaking Ground Loops

Product Notifications

Please login to your MyLinear account for notifications of datasheet updates, new document releases and LTspice model announcements for your favorite products. If you do not have a MyLinear account you may Sign Up Now.

Forgot your password? Click here.
Need help? Email mylinear@linear.com with questions and comments.

Design Tools

LTspice

LTspice® software is a powerful, fast and free simulation tool, schematic capture and waveform viewer with enhancements and models for improving the simulation of switching regulators. Click here to download LTspice

Models for the following parts are available in LTspice:
LTM9100

Linduino

Linduino is an Arduino compatible platform for developing and distributing firmware libraries and code for SPI and I²C-compatible integrated circuits. The Linduino One board interfaces to more than 300 QuikEval demonstration cards, supporting a variety of product types including analog-to-digital converters (ADCs)digital-to-analog converters (DACs)power monitors, and more. Firmware libraries for individual devices are written in C and designed to be portable to a wide variety of processors and microcontrollers. Each library has a demonstration program that can be uploaded to the Linduino One platform to allow the circuit and software to be quickly and easily verified.

Click here for more information on Linduino

Code

Linduino is Linear Technology's Arduino compatible system for developing and distributing firmware libraries and example code for Linear Technology’s integrated circuits. The code below can be downloaded or copied and pasted into your project. Please visit the Linduino Home Page for demo board, manual and setup information.

This part is Code Supported: There is example code available for this part. The code below may rely on other drivers available in the full library.

Download LTM9100 - DC2423A.ino File

/*!
Linear Technology DC2423A Demonstration Board.
LTM9100: Anyside™ High Voltage Isolated Switch Controller with I²C Command and Telemetry

@verbatim

NOTES
  Setup:
   Set the terminal baud rate to 115200 and select the newline terminator.

USER INPUT DATA FORMAT:
 decimal : 1024
 hex     : 0x400
 octal   : 02000  (leading 0 "zero")
 binary  : B10000000000
 float   : 1024.0

@endverbatim

http://www.linear.com/product/LTM9100

http://www.linear.com/product/LTC9100#demoboards

REVISION HISTORY
$Revision: 6835 $
$Date: 2017-03-30 11:37:36 -0700 (Thu, 30 Mar 2017) $

Copyright (c) 2013, Linear Technology Corp.(LTC)
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of Linear Technology Corp.

The Linear Technology Linduino is not affiliated with the official Arduino team.
However, the Linduino is only possible because of the Arduino team's commitment
to the open-source community.  Please, visit http://www.arduino.cc and
http://store.arduino.cc , and consider a purchase that will help fund their
ongoing work.
*/

/*! @file
    @ingroup LTM9100
*/

#include <Arduino.h>
#include <stdint.h>
#include "Linduino.h"
#include "UserInterface.h"
#include "LT_I2C.h"
#include "QuikEval_EEPROM.h"
#include "LTM9100.h"

float sense_resistor = 0.008;     //default resistance in ohms
float adin_gain = 0.035;          //default
float adin2_gain = 0.035;         //default
uint8_t i2c_address = 0x10;       //default

//! Initialize Linduino
void setup()
{
  //Port initialization
  DDRD = DDRD | B00111100;      // Sets data direction of Digital Pins 0-7 (Logical OR to not interfere with Rx and Tx)
  PORTD = B00000000;            // Initializes Digital Pins 0-7 to LOW
  DDRB = B00011111;             // Sets data direction of Digital Pins 8-13
  PORTB = B00000001;            // Initializes Digital Pin 8 HIGH and 9-13 to LOW, Pin 8 is I2C Linduino select bit
  i2c_enable();                 // Initializes Linduino I2C port.
  Serial.begin(115200);         // Initialize the serial port to the PC
  print_title();
  print_prompt();
}

//! Repeats Linduino loop
void loop()
{
  int8_t ack=0;
  uint8_t user_command;
  uint8_t data;
  uint8_t user_register;

  if (Serial.available())
  {
    user_command = read_int();                              //! Reads the user command
    Serial.println(user_command);                         // Print user command

    //! Reads or writes to a LTM9100 and prints result.
    switch (user_command)
    {
      case 1:
        // Read every register and print it's data.
        ack |= LTM9100_print_all_registers(i2c_address);
        break;
      case 2:
        // Read a single register and print it's data.
        Serial.print(F("\nAddress (in hex with '0x' prefix) of register to read: "));
        user_register = read_int();
        Serial.print("0x");
        Serial.println(user_register, HEX);
        if (!valid_register(user_register, reg_read_list, sizeof(reg_read_list)))
        {
          Serial.println(F("  Invalid input."));
          break;
        }
        ack |= LTM9100_register_read(i2c_address, user_register, &data);
        if (!ack)
        {
          Serial.print("Register data: 0x");
          Serial.println(data, HEX);
        }
        break;
      case 3:
        // Write a byte to a chosen register.
        Serial.print(F("\nAddress (in hex with '0x' prefix) of register to write: "));
        user_register = read_int();
        Serial.print("0x");
        Serial.println(user_register, HEX);
        if (!valid_register(user_register, reg_write_list, sizeof(reg_write_list)))
        {
          Serial.println(F("  Invalid input."));
          break;
        }
        Serial.print(F("Data (in hex with '0x' prefix) to write: "));
        data = read_int();
        Serial.println(data, HEX);
        ack |= LTM9100_register_write(i2c_address, user_register, data);
        if (!ack)
        {
          Serial.print("0x");
          Serial.print(data, HEX);
          Serial.print(" written to register 0x");
          Serial.println(user_register, HEX);
        }
        break;
      case 4:
        // Set a single bit within a chosen register.
        Serial.print(F("\nAddress (in hex with '0x' prefix) of register: "));
        user_register = read_int();
        Serial.print("0x");
        Serial.println(user_register, HEX);
        if (!valid_register(user_register, reg_write_list, sizeof(reg_write_list)))
        {
          Serial.println(F("  Invalid input."));
          break;
        }
        Serial.print(F("Bit position (0-7) to set: "));
        data = read_int();
        if (data < 0 || data > 7)
        {
          Serial.println(F("  Invalid input."));
          break;
        }
        Serial.println(data, DEC);
        ack |= LTM9100_bit_set(i2c_address, user_register, data);
        if (!ack)
        {
          Serial.print("Bit set. Register data is now 0x");
          ack |= LTM9100_register_read(i2c_address, user_register, &data);
          Serial.println(data, HEX);
        }
        break;
      case 5:
        // Clear a single bit within a chosen register.
        Serial.print(F("\nAddress (in hex with '0x' prefix) of register: "));
        user_register = read_int();
        Serial.print("0x");
        Serial.println(user_register, HEX);
        if (!valid_register(user_register, reg_write_list, sizeof(reg_write_list)))
        {
          Serial.println(F("  Invalid input."));
          break;
        }
        Serial.print(F("Bit position (0-7) to clear: "));
        data = read_int();
        if (data < 0 || data > 7)
        {
          Serial.println(F("Invalid input."));
          break;
        }
        Serial.println(data, DEC);
        ack |= LTM9100_bit_clear(i2c_address, user_register, data);
        if (!ack)
        {
          Serial.print("Bit cleared. Register data is now 0x");
          ack |= LTM9100_register_read(i2c_address, user_register, &data);
          Serial.println(data, HEX);
        }
        break;
      case 6:
        // Write a byte to a chosen register via the Mass Write I2C address.
        Serial.print(F("\nAddress (in hex with '0x' prefix) of register to write: "));
        user_register = read_int();
        Serial.print("0x");
        Serial.println(user_register, HEX);
        if (!valid_register(user_register, reg_write_list, sizeof(reg_write_list)))
        {
          Serial.println(F("  Invalid input."));
          break;
        }
        Serial.print(F("Data (in hex with '0x' prefix) to write: "));
        data = read_int();
        Serial.println(data, HEX);
        ack |= LTM9100_register_write(0x1F, user_register, data);
        if (!ack)
        {
          Serial.print("0x");
          Serial.print(data, HEX);
          Serial.print(" written to register 0x");
          Serial.println(user_register, HEX);
        }
        break;
      case 7:
        ack |= menu_read_status();                      // Print status menu
        break;
      case 8:
        ack |= menu_read_write_faults_alerts(false);    // Print Faults menu
        break;
      case 9:
        ack |= menu_read_write_faults_alerts(true);     // Print Alert setting menu
        break;
      case 10:
        ack |= menu_read_write_controls();              // Print Controls menu
        break;
      case 11:
        ack |= menu_read_write_adc_params();            // Print ADC menu
        break;
      case 12:
        ack |= LTM9100_continuous_read_all_registers(i2c_address);
        break;
    }
    if (ack != 0)
    {
      Serial.print(F("Error: No Acknowledge. \n"));
    }
    print_prompt();
  }
}

// Function Definitions

//! Prints a warning if the demo board is not detected.
void print_warning_prompt()
{
  Serial.println(F("\nWarning: Demo board not detected. Linduino will attempt to proceed."));
}

//! Prints the title block when program first starts.
void print_title()
{
  Serial.print(F("\n*****************************************************************\n"));
  Serial.print(F("* LTM9100 Demonstration Program                                 *\n"));
  Serial.print(F("*                                                               *\n"));
  Serial.print(F("* This program demonstrates sending and receiving data from     *\n"));
  Serial.print(F("* the LTM9100 via I2C.                                          *\n"));
  Serial.print(F("*                                                               *\n"));
  Serial.print(F("* Set the baud rate to 115200 and select the newline terminator.*\n"));
  Serial.print(F("*                                                               *\n"));
  Serial.print(F("*****************************************************************\n"));
}

// Prints main menu.
void print_prompt()
{
  //! Displays the Read/Write Registers menu
  Serial.print(F("\nRead/Write Registers\n\n"));
  Serial.print(F("  1-Read All Registers\n"));
  Serial.print(F("  2-Read Single Register\n"));
  Serial.print(F("  3-Write Single Register\n"));
  Serial.print(F("  4-Set Bit\n"));
  Serial.print(F("  5-Clear Bit\n"));
  Serial.print(F("  6-Write Register to Mass Write Address\n"));
  Serial.println(F("  7-Read Status"));
  Serial.println(F("  8-Read/Write Faults"));
  Serial.println(F("  9-Read/Write Alerts"));
  Serial.println(F("  10-Read/Write Controls"));
  Serial.println(F("  11-Read/Write ADC parameters"));
  Serial.println(F("  12-Continuously Read Registers"));
  Serial.print(F("\nEnter a command: "));
}

int8_t menu_read_status()
{
  int8_t ack=0;
  uint8_t user_command;
  uint8_t data;
  uint8_t user_register = LTM_9100_STATUS_A_REG;
  uint8_t user_bit;
  do
  {
    //! Displays the Read Status menu
    Serial.print(F("\nRead Status\n\n"));
    Serial.print(F("  1-Gate Status\n"));
    Serial.print(F("  2-PG Input Pin Status\n"));
    Serial.print(F("  3-FET Status\n"));
    Serial.print(F("  4-Overcurrent Condition\n"));
    Serial.print(F("  5-Undervoltage Condition\n"));
    Serial.print(F("  6-Overvoltage Condition\n"));
    Serial.print(F("  m-Main Menu\n"));
    Serial.print(F("\nEnter a command: "));

    user_command = read_int();                              //! Reads the user command
    if (user_command == 'm')                                // Print m if it is entered
      Serial.print(F("m\n"));
    else
      Serial.println(user_command);                         // Print user command

    //! Reads LTM9100 and prints result.
    switch (user_command)
    {
      case 1:
        ack |= LTM9100_bit_read(i2c_address, user_register, LTM_9100_STATUS_GATE, &data);
        Serial.print(F("Gate State: "));
        (data)?Serial.println(F("On")):Serial.println(F("Off"));
        break;
      case 2:
        ack |= LTM9100_bit_read(i2c_address, user_register, LTM_9100_STATUS_PGI, &data);
        Serial.print(F("PG Input State: "));
        (data)?Serial.println(F("High")):Serial.println(F("Low"));
        break;
      case 3:
        ack |= LTM9100_bit_read(i2c_address, user_register, LTM_9100_STATUS_FET, &data);
        Serial.print(F("FET State: "));
        (data)?Serial.println(F("Short")):Serial.println(F("No Short"));
        break;
      case 4:
        ack |= LTM9100_bit_read(i2c_address, user_register, LTM_9100_STATUS_OC, &data);
        Serial.print(F("Overcurrent: "));
        (data)?Serial.println(F("Yes")):Serial.println(F("No"));
        break;
      case 5:
        ack |= LTM9100_bit_read(i2c_address, user_register, LTM_9100_STATUS_UV, &data);
        Serial.print(F("Undervoltage: "));
        (data)?Serial.println(F("Yes")):Serial.println(F("No"));
        break;
      case 6:
        ack |= LTM9100_bit_read(i2c_address, user_register, LTM_9100_STATUS_OV, &data);
        Serial.print(F("Overvoltage: "));
        (data)?Serial.println(F("Yes")):Serial.println(F("No"));
        break;
      default:
        if (user_command != 'm')
          Serial.println("Invalid Selection");
        break;
    }

  }
  while ((user_command != 'm') && (ack != 1));
  return(ack);
}

static int8_t ask_clear_set_bit(uint8_t i2c_address, uint8_t register_address, uint8_t bit_number)
{
  int8_t ack = 0;
  uint8_t user_bit;
  Serial.println(F("0=Clear/Disable, 1=Set/Enable:"));
  user_bit = read_int();
  if (user_bit > 1)
    Serial.println(F("  Invalid input."));
  else
    ack |= (user_bit)?LTM9100_bit_set(i2c_address, register_address, bit_number):LTM9100_bit_clear(i2c_address, register_address, bit_number);

  return ack;
}

int8_t menu_read_write_faults_alerts(bool alerts)
{
  int8_t ack=0;
  uint8_t user_command;
  uint8_t data;
  uint8_t user_register = (alerts)?LTM_9100_ALERT_C_REG:LTM_9100_FAULT_B_REG;

  do
  {
    if (!alerts) //! Displays the Read/Write Faults menu
    {
      Serial.print(F("\nRead/Write Faults\n\n"));
      Serial.print(F("  1-Read PGIO_HIGH\n"));
      Serial.print(F("  2-Read FET_FAULT\n"));
      Serial.print(F("  3-Read OC_FAULT\n"));
      Serial.print(F("  4-Read UV_FAULT\n"));
      Serial.print(F("  5-Read OV_FAULT\n"));
      Serial.print(F("  6-Clear/Set PGIO_HIGH\n"));
      Serial.print(F("  7-Clear/Set FET_FAULT\n"));
      Serial.print(F("  8-Clear/Set OC_FAULT\n"));
      Serial.print(F("  9-Clear/Set UV_FAULT\n"));
      Serial.print(F("  10-Clear/Set OV_FAULT\n"));
    }
    else //! Displays the Read/Write Alerts menu
    {
      Serial.print(F("\nRead/Write Alerts\n\n"));
      Serial.print(F("  1-Read PGIO_OUT\n"));
      Serial.print(F("  2-Read FET_ALERT\n"));
      Serial.print(F("  3-Read OC_ALERT\n"));
      Serial.print(F("  4-Read UV_ALERT\n"));
      Serial.print(F("  5-Read OV_ALERT\n"));
      Serial.print(F("  6-Disable/Enable PGIO_OUT\n"));
      Serial.print(F("  7-Disable/Enable FET_ALERT\n"));
      Serial.print(F("  8-Disable/Enable OC_ALERT\n"));
      Serial.print(F("  9-Disable/Enable UV_ALERT\n"));
      Serial.print(F("  10-Disable/Enable OV_ALERT\n"));
    }
    Serial.print(F("  m-Main Menu\n"));
    Serial.print(F("\nEnter a command: "));

    user_command = read_int();                              //! Reads the user command
    if (user_command == 'm')                                // Print m if it is entered
      Serial.print(F("m\n"));
    else
      Serial.println(user_command);                         // Print user command

    //! Reads or writes to a LTM9100 and prints result.
    switch (user_command)
    {
      case 1:
        ack |= LTM9100_bit_read(i2c_address, user_register, LTM_9100_FAULT_PGI, &data);
        Serial.print(F("PGIO: "));
        (data)?Serial.println(F("Yes")):Serial.println(F("No"));
        break;
      case 2:
        ack |= LTM9100_bit_read(i2c_address, user_register, LTM_9100_FAULT_FET, &data);
        Serial.print(F("FET Short Detected: "));
        (data)?Serial.println(F("Fault")):Serial.println(F("No Fault"));
        break;
      case 3:
        ack |= LTM9100_bit_read(i2c_address, user_register, LTM_9100_FAULT_OC, &data);
        Serial.print(F("Overcurrent: "));
        (data)?Serial.println(F("Fault")):Serial.println(F("No Fault"));
        break;
      case 4:
        ack |= LTM9100_bit_read(i2c_address, user_register, LTM_9100_FAULT_UV, &data);
        Serial.print(F("Undervoltage: "));
        (data)?Serial.println(F("Fault")):Serial.println(F("No Fault"));
        break;
      case 5:
        ack |= LTM9100_bit_read(i2c_address, user_register, LTM_9100_FAULT_OV, &data);
        Serial.print(F("Overvoltage: "));
        (data)?Serial.println(F("Fault")):Serial.println(F("No Fault"));
        break;
      case 6:
        ack |= ask_clear_set_bit(i2c_address, user_register, LTM_9100_FAULT_PGI);
        break;
      case 7:
        ack |= ask_clear_set_bit(i2c_address, user_register, LTM_9100_FAULT_FET);
        break;
      case 8:
        ack |= ask_clear_set_bit(i2c_address, user_register, LTM_9100_FAULT_OC);
        break;
      case 9:
        ack |= ask_clear_set_bit(i2c_address, user_register, LTM_9100_FAULT_UV);
        break;
      case 10:
        ack |= ask_clear_set_bit(i2c_address, user_register, LTM_9100_FAULT_OV);
        break;
      default:
        if (user_command != 'm')
          Serial.println("Invalid Selection");
        break;
    }

  }
  while ((user_command != 'm') && (ack != 1));
  return(ack);
}

int8_t menu_read_write_controls()
{
  int8_t ack=0;
  uint8_t user_command;
  uint8_t data;
  uint8_t user_register = LTM_9100_CTRL_D_REG;
  uint8_t user_bit;

  do
  {
    //! Displays the Read/Write Controls menu
    Serial.print(F("\nRead/Write Controls\n\n"));
    Serial.print(F("  1-Read PGIO_CONFIG\n"));
    Serial.print(F("  2-Read ADC_WRITE\n"));
    Serial.print(F("  3-Read GATE_CTRL\n"));
    Serial.print(F("  4-Read OC_AUTO\n"));
    Serial.print(F("  5-Read UV_AUTO\n"));
    Serial.print(F("  6-Read OV_AUTO\n"));
    Serial.print(F("  7-Disable/Enable PGIO_CONFIG\n"));
    Serial.print(F("  8-Disable/Enable ADC_WRITE\n"));
    Serial.print(F("  9-Disable/Enable GATE_CTRL\n"));
    Serial.print(F("  10-Disable/Enable OC_AUTO\n"));
    Serial.print(F("  11-Disable/Enable UV_AUTO\n"));
    Serial.print(F("  12-Disable/Enable OV_AUTO\n"));
    Serial.print(F("  m-Main Menu\n"));
    Serial.print(F("\nEnter a command: "));

    user_command = read_int();                              //! Reads the user command
    if (user_command == 'm')                                // Print m if it is entered
      Serial.print(F("m\n"));
    else
      Serial.println(user_command);                         // Print user command

    //! Reads or writes to a LTM9100 and prints result.
    switch (user_command)
    {
      case 1:
        ack |= LTM9100_register_read(i2c_address, user_register, &data);
        data &= LTM_9100_CTRL_PGIO_CFG_MASK;
        Serial.print(F("PGIO Config: "));
        if (~data & 0x40)
          Serial.println(F("Power Good, Open Drain"));
        else if (data & 0x80)
          Serial.println(F("General Purpose Input"));
        else
          Serial.println(F("General Purpose Output"));
        break;
      case 2:
        ack |= LTM9100_bit_read(i2c_address, user_register, LTM_9100_CTRL_ADC_WRITE, &data);
        Serial.print(F("ADC write: "));
        (data)?Serial.println(F("Enabled")):Serial.println(F("Disabled"));
      case 3:
        ack |= LTM9100_bit_read(i2c_address, user_register, LTM_9100_CTRL_GATE_CTRL, &data);
        Serial.print(F("Gate State: "));
        (data)?Serial.println(F("Enabled")):Serial.println(F("Disabled"));
        break;
        break;
      case 4:
        ack |= LTM9100_bit_read(i2c_address, user_register, LTM_9100_CTRL_OC, &data);
        Serial.print(F("Overcurrent: "));
        (data)?Serial.println(F("Enabled")):Serial.println(F("Disabled"));
        break;
      case 5:
        ack |= LTM9100_bit_read(i2c_address, user_register, LTM_9100_CTRL_UV, &data);
        Serial.print(F("Undervoltage: "));
        (data)?Serial.println(F("Enabled")):Serial.println(F("Disabled"));
        break;
      case 6:
        ack |= LTM9100_bit_read(i2c_address, user_register, LTM_9100_CTRL_OV, &data);
        Serial.print(F("Overvoltage: "));
        (data)?Serial.println(F("Enabled")):Serial.println(F("Disabled"));
        break;
      case 7:
        Serial.println(F("0,2=Power Good, 1=General Purpose Output, 3=General Purpose Input:"));
        user_bit = read_int();
        if (user_bit > 3)
          Serial.println(F("  Invalid input."));
        else
        {
          ack |= LTM9100_register_read(i2c_address, user_register, &data);
          data &= ~LTM_9100_CTRL_PGIO_CFG_MASK;
          data |= user_bit<<LTM_9100_CTRL_PGIO_CFG;
          LTM9100_register_write(i2c_address, user_register, data);
        }
        break;
      case 8:
        ack |= ask_clear_set_bit(i2c_address, user_register, LTM_9100_CTRL_ADC_WRITE );
        break;
      case 9:
        ack |= ask_clear_set_bit(i2c_address, user_register, LTM_9100_CTRL_GATE_CTRL);
        break;
      case 10:
        ack |= ask_clear_set_bit(i2c_address, user_register, LTM_9100_CTRL_OC);
        break;
      case 11:
        ack |= ask_clear_set_bit(i2c_address, user_register, LTM_9100_CTRL_UV);
        break;
      case 12:
        ack |= ask_clear_set_bit(i2c_address, user_register, LTM_9100_CTRL_OV);
        break;
      default:
        if (user_command != 'm')
          Serial.println("Invalid Selection");
        break;
    }

  }
  while ((user_command != 'm') && (ack != 1));
  return(ack);
}

static void set_adc_scaling_factor(float *data)
{
  Serial.print(F("Current value: "));
  Serial.println(*data, 4);
  Serial.print(F("Enter new value: "));
  *data = read_float();
  Serial.println("");
}

int8_t menu_read_write_adc_params()
{
  int8_t ack=0;
  uint8_t user_command;
  float data;

  do
  {
    //! Displays the Read/Write ADC menu
    Serial.print(F("\nRead/Write ADCs \n\n"));
    Serial.print(F("  1-Read ADC Current Sense Voltage\n"));
    Serial.print(F("  2-Read ADIN Voltage\n"));
    Serial.print(F("  3-Read ADIN2 Voltage or Temperature\n"));
    Serial.print(F("  4-Configure Current Sense Resistor(ohms)\n"));
    Serial.print(F("  5-Configure ADIN Gain(defaults: 0.035[A], 0.006[B])\n"));
    Serial.print(F("  6-Configure ADIN2 Gain(defaults: 0.035[A], 0.006[B], or 0.004V/Kelvin[A/B])\n"));
    Serial.print(F("  m-Main Menu\n"));
    Serial.print(F("\nEnter a command: "));

    user_command = read_int();                              //! Reads the user command
    if (user_command == 'm')                                // Print m if it is entered
      Serial.print(F("m\n"));
    else
    {
      Serial.println(user_command);                         // Print user command
    }

    //! Reads or writes to a LTM9100 and prints result.
    switch (user_command)
    {
      case 1:
        ack |= LTM9100_adc_read(i2c_address, LTM_9100_SENSE_E_REG, &data);
        break;
      case 2:
        ack |= LTM9100_adc_read(i2c_address, LTM_9100_ADIN_I_REG, &data);
        break;
      case 3:
        ack |= LTM9100_adc_read(i2c_address, LTM_9100_ADIN2_G_REG, &data);
        break;
      case 4:
        set_adc_scaling_factor(&sense_resistor);
        break;
      case 5:
        set_adc_scaling_factor(&adin_gain);
        break;
      case 6:
        set_adc_scaling_factor(&adin2_gain);
        break;
      default:
        if (user_command != 'm')
          Serial.println("Invalid Selection");
        break;
    }

  }
  while ((user_command != 'm') && (ack != 1));
  return(ack);
}

Download LTM9100 - Linduino CPP File

/*!
LTM9100: Anyside™ High Voltage Isolated Switch Controller with I²C Command and Telemetry

@verbatim

The LTM9100 μModule controller is a complete, galvanically isolated switch controller
with I2C interface, for use as a load switch or hot swap controller. The load is soft
started and controlled by an external N-channel MOSFET switch.

@endverbatim

http://www.linear.com/product/LTM9100

http://www.linear.com/product/LTC9100#demoboards

REVISION HISTORY
$Revision: 6835 $
$Date: 2017-03-30 11:37:36 -0700 (Thu, 30 Mar 2017) $

Copyright (c) 2013, Linear Technology Corp.(LTC)
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of Linear Technology Corp.

The Linear Technology Linduino is not affiliated with the official Arduino team.
However, the Linduino is only possible because of the Arduino team's commitment
to the open-source community.  Please, visit http://www.arduino.cc and
http://store.arduino.cc , and consider a purchase that will help fund their
ongoing work.
*/

//! @ingroup Switching_Regulators
//! @{
//! @defgroup LTM9100 LTM9100: Anyside™ High Voltage Isolated Switch Controller with I²C Command and Telemetry.

//! @}

/*! @file
    @ingroup LTM9100
    Library for LTM9100 Anyside™ High Voltage Isolated Switch Controller with I²C Command and Telemetry.
*/

#include <Arduino.h>
#include <stdint.h>
#include "Linduino.h"
#include "LT_I2C.h"
#include "LTM9100.h"

uint8_t reg_read_list[10] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09};
uint8_t reg_write_list[9] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09};

// Reads an 8-bit register from the LTM9100 using the standard repeated start format.
int8_t LTM9100_register_read(uint8_t i2c_address, uint8_t register_address, uint8_t *register_data)
{
  int8_t ack = 0;
  ack = i2c_read_byte_data(i2c_address, register_address, register_data);
  return(ack);
}

// Read the specified ADC value (SENSE, ADIN, ADIN2) and output in human readable format to the serial console.
int8_t LTM9100_adc_read(uint8_t i2c_address, uint8_t base_address, float *register_data)
{
  uint8_t data_LSBs, data_MSBs;
  uint16_t data_ten_bit;
  int8_t ack = 0;
  ack |= LTM9100_register_read(i2c_address, base_address, &data_MSBs);
  ack |= LTM9100_register_read(i2c_address, base_address+1, &data_LSBs);
  data_ten_bit = ((uint16_t)data_MSBs<<2) | ((uint16_t)data_LSBs>>6);

  switch (base_address)
  {
    case LTM_9100_SENSE_E_REG:
      *register_data = ((float)data_ten_bit * LTM_9100_SENSE_mV_PER_TICK)/sense_resistor;
      Serial.print(F("ADC Current Sense Voltage(mA): "));
      break;
    case LTM_9100_ADIN_I_REG:
      *register_data = ((float)data_ten_bit * LTM_9100_ADIN_V_PER_TICK)/adin_gain;
      Serial.print(F("ADIN Voltage(V): "));
      break;
    case LTM_9100_ADIN2_G_REG:
      *register_data = ((float)data_ten_bit * LTM_9100_ADIN2_V_PER_TICK)/adin2_gain;
      Serial.print(F("ADIN2 Voltage(V or K): "));
      break;
    default:
      return ack;
  }

  Serial.println(*register_data, 4);
  return ack;
}

// Writes to an 8-bit register inside the LTM9100 using the standard I2C repeated start format.
int8_t LTM9100_register_write(uint8_t i2c_address, uint8_t register_address, uint8_t register_data)
{
  int8_t ack = 0;
  ack = i2c_write_byte_data(i2c_address, register_address, register_data);
  return(ack);
}

// Sets any bit inside the LTM9100 using the standard I2C repeated start format.
int8_t LTM9100_bit_set(uint8_t i2c_address, uint8_t register_address, uint8_t bit_number)
{
  uint8_t register_data;
  uint8_t bit_mask;
  int8_t ack = 0;
  bit_mask = 0x01 << bit_number;
  ack |= LTM9100_register_read(i2c_address, register_address, &register_data);  //Read register
  register_data = register_data | bit_mask;  //Set the bit at bit_address
  ack |= LTM9100_register_write(i2c_address, register_address, register_data);  //Write new data to register
  return(ack);
}

// Clears any bit inside the LTM9100 using the standard I2C repeated start format.
int8_t LTM9100_bit_clear(uint8_t i2c_address, uint8_t register_address, uint8_t bit_number)
{
  uint8_t register_data;
  uint8_t bit_mask;
  int8_t ack = 0;
  bit_mask = 0x01 << bit_number;
  ack |= LTM9100_register_read(i2c_address, register_address, &register_data);  //Read register
  register_data = register_data & (~bit_mask);  //Clears the bit at bit_address
  ack |= LTM9100_register_write(i2c_address, register_address, register_data);  //Write new data to register
  return(ack);
}

// Read the bit specified by bit_number from the LTM9100.
int8_t LTM9100_bit_read(uint8_t i2c_address, uint8_t register_address, uint8_t bit_number, uint8_t *register_data)
{
  int8_t ack = 0;
  ack = LTM9100_register_read(i2c_address, register_address, register_data);
  *register_data = (*register_data >> bit_number) & 0x1;
  return ack;
}

// Attempts to read a byte from the I2C bus using the alert address (0xC) to ascertain pending alerts on the bus.
int8_t LTM9100_alert_read(uint8_t *register_data)
{
  int8_t ack = 0;
  ack = i2c_read_byte(0x0C, register_data);
  return(ack);
}

// Read all LTM9100 registers and output to the serial console.
int8_t LTM9100_print_all_registers(uint8_t i2c_address)
{
  int8_t ack = 0;
  uint8_t data;
  uint8_t i;
  for (i=0; i<sizeof(reg_read_list); i++)
  {
    ack |= LTM9100_register_read(i2c_address, reg_read_list[i], &data);   //! Read register
    Serial.print("Register 0x");
    Serial.print(reg_read_list[i], HEX);
    Serial.print(":\t");
    if (!ack)
    {
      Serial.print("0x");
      Serial.println(data, HEX);
    }
    else
    {
      Serial.println("No Acknowledge");
    }
  }
  return ack;
}

// Read all LTM9100 registers and output to the serial console every second until a key press is detected.
int8_t LTM9100_continuous_read_all_registers(uint8_t i2c_address)
{
  int8_t ack = 0;
  uint8_t count = 0;
  float data = 0;
  char anykey[1];

  //Note: Arduino serial monitor doesn't support all VT100 commands,
  //thus the continuous_read can't scrollback and rewrite the latest register values.
  while (count < 1)
  {
    ack |= LTM9100_print_all_registers(i2c_address);
    ack |= LTM9100_adc_read(i2c_address, LTM_9100_SENSE_E_REG, &data);
    ack |= LTM9100_adc_read(i2c_address, LTM_9100_ADIN_I_REG, &data);
    ack |= LTM9100_adc_read(i2c_address, LTM_9100_ADIN2_G_REG, &data);
    Serial.println("");

    count = Serial.readBytes(anykey, 1); //default timeout is 1000 milliseconds. Change via the setTimeout method of Serial.
  }

  return ack;
}

// Check if user_register is a valid register for the LTM9100.
boolean valid_register(uint8_t user_register, uint8_t register_array[], uint8_t array_length)
{
  uint8_t i=0;
  for (i=0; i<array_length; i++)
  {
    if (register_array[i] == user_register)
    {
      return true;
    }
  }
  return false;
}

Download LTM9100 - Linduino Header File

/*!
LTM9100: Anyside™ High Voltage Isolated Switch Controller with I²C Command and Telemetry

@verbatim

The LTM9100 μModule controller is a complete, galvanically isolated switch controller
with I2C interface, for use as a load switch or hot swap controller. The load is soft
started and controlled by an external N-channel MOSFET switch.

@endverbatim

http://www.linear.com/product/LTM9100

http://www.linear.com/product/LTC9100#demoboards

REVISION HISTORY
$Revision: 6835 $
$Date: 2017-03-30 11:37:36 -0700 (Thu, 30 Mar 2017) $

Copyright (c) 2013, Linear Technology Corp.(LTC)
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of Linear Technology Corp.

The Linear Technology Linduino is not affiliated with the official Arduino team.
However, the Linduino is only possible because of the Arduino team's commitment
to the open-source community.  Please, visit http://www.arduino.cc and
http://store.arduino.cc , and consider a purchase that will help fund their
ongoing work.
*/

/*! @file
    @ingroup LTM9100
    Header for LTM9100 Anyside™ High Voltage Isolated Switch Controller with I²C Command and Telemetry.
*/

#ifndef LTM9100_H
#define LTM9100_H

#define LTM_9100_STATUS_A_REG 0x00
#define LTM_9100_FAULT_B_REG  0x01
#define LTM_9100_ALERT_C_REG  0x02
#define LTM_9100_CTRL_D_REG   0x03
#define LTM_9100_SENSE_E_REG  0x04
#define LTM_9100_SENSE_F_REG  0x05
#define LTM_9100_ADIN2_G_REG  0x06
#define LTM_9100_ADIN2_H_REG  0x07
#define LTM_9100_ADIN_I_REG   0x08
#define LTM_9100_ADIN_J_REG   0x09

#define LTM_9100_STATUS_GATE  0x07
#define LTM_9100_STATUS_PGI   0x06
#define LTM_9100_STATUS_FET   0x05
#define LTM_9100_STATUS_OC    0x02
#define LTM_9100_STATUS_UV    0x01
#define LTM_9100_STATUS_OV    0x00

#define LTM_9100_FAULT_PGI    0x06
#define LTM_9100_FAULT_FET    0x05
#define LTM_9100_FAULT_OC     0x02
#define LTM_9100_FAULT_UV     0x01
#define LTM_9100_FAULT_OV     0x00

#define LTM_9100_ALERT_PGO    LTM_9100_FAULT_PGI
#define LTM_9100_ALERT_FET    LTM_9100_FAULT_FET
#define LTM_9100_ALERT_OC     LTM_9100_FAULT_OC
#define LTM_9100_ALERT_UV     LTM_9100_FAULT_UV
#define LTM_9100_ALERT_OV     LTM_9100_FAULT_OV

#define LTM_9100_CTRL_PGIO_CFG    0x06
#define LTM_9100_CTRL_PGIO_CFG_MASK 0xC0
#define LTM_9100_CTRL_ADC_WRITE   0x05
#define LTM_9100_CTRL_GATE_CTRL   0x03
#define LTM_9100_CTRL_OC      0x02
#define LTM_9100_CTRL_UV        0x01
#define LTM_9100_CTRL_OV        0x00

#define LTM_9100_SENSE_mV_PER_TICK  0.0625
#define LTM_9100_ADIN_V_PER_TICK  0.0025
#define LTM_9100_ADIN2_V_PER_TICK 0.0025

extern uint8_t i2c_address;       //7-bit version of LTM9100 I2C device addr determined by ADR0 & ADR1 (divide datasheet address by 2). ADR0/1 low: 0x20 -> 0x10
extern uint8_t reg_read_list[10];
extern uint8_t reg_write_list[9];

extern float sense_resistor;
extern float adin_gain;
extern float adin2_gain;


//! Reads an 8-bit register from the LTM9100 using the standard repeated start format.
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTM9100_register_read(uint8_t i2c_address, uint8_t register_address, uint8_t *register_data);

//! Read the specified ADC value (SENSE, ADIN, ADIN2) and output in human readable format to the serial console.
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTM9100_adc_read(uint8_t i2c_address, uint8_t base_address, float *register_data);

//! Writes to an 8-bit register inside the LTM9100 using the standard I2C repeated start format.
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTM9100_register_write(uint8_t i2c_address, uint8_t register_address, uint8_t register_data);

//! Sets any bit inside the LTM9100 using the standard I2C repeated start format.
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTM9100_bit_set(uint8_t i2c_address, uint8_t register_address, uint8_t bit_number);

//! Clears any bit inside the LTM9100 using the standard I2C repeated start format.
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTM9100_bit_clear(uint8_t i2c_address, uint8_t register_address, uint8_t bit_number);

//! Read the bit specified by bit_number from the LTM9100.
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTM9100_bit_read(uint8_t i2c_address, uint8_t register_address, uint8_t bit_number, uint8_t *register_data);

//! Attempts to read a byte from the I2C bus using the alert address (0xC) to ascertain pending alerts on the bus.
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTM9100_alert_read(uint8_t *register_data);

//! Read all LTM9100 registers and output to the serial console.
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTM9100_print_all_registers(uint8_t i2c_address);

//! Read all LTM9100 registers and output to the serial console every second until a key press is detected.
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTM9100_continuous_read_all_registers(uint8_t i2c_address);

//! Check if user_register is a valid register for the LTM9100.
//! @return Returns the validity of user_register against the the supplied register set.
boolean valid_register(uint8_t user_register, uint8_t register_array[], uint8_t array_length);

#endif

Technical Support