LTC3676/LTC3676-1 - Power Management Solution for Application Processors

Features

  • Quad I2C Adjustable High Efficiency Step Down DC/DC Converters: 2.5A, 2.5A, 1.5A, 1.5A
  • Three 300mA LDO Regulators (Two Adjustable)
  • DDR Power Solution with VTT and VTTR Reference
  • Pushbutton ON/OFF Control with System Reset
  • Independent Enable Pin-Strap or I2C Sequencing
  • Programmable Autonomous Power-Down Control
  • Dynamic Voltage Scaling
  • Power Good and Reset Functions
  • Selectable 2.25MHz or 1.12MHz Switching Frequency
  • Always Alive 25mA LDO Regulator
  • 12μA Standby Current
  • Low Profile 40-Lead 6mm × 6mm × 0.75mm QFN Package

Typical Application

LTC3676 Typical Application
LTC3676 Typical Application

Description

The LTC®3676 is a complete power management solution for advanced portable application processor-based systems. The device contains four synchronous step-down DC/DC converters for core, memory, I/O, and system on-chip (SoC) rails and three 300mA LDO regulators for low noise analog supplies. The LTC3676-1 has a ±1.5A buck regulator configured to support DDR termination plus a VTTR reference output. An I2C serial port is used to control regulator enables, power-down sequencing, output voltage levels, dynamic voltage scaling, operating modes and status reporting.

Regulator start-up is sequenced by connecting outputs to enable pins in the desired order or via the I2C port. System power-on, power-off and reset functions are controlled by pushbutton interface, pin inputs, or I2C.

The LTC3676 supports i.MX, PXA and OMAP processors with eight independent rails at appropriate power levels. Other features include interface signals such as the VSTB pin that toggles between programmed run and standby output voltages on up to four rails simultaneously. The device is available in a 40-lead 6mm × 6mm QFN package.

Packaging

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

QFN-40

LTC3676 Package Drawing
LTC3676 Package Drawing

Order Info

Package Variations and Pricing

Part Number Package Pins Temp Price (1-99) Price (1k)* RoHS Data
LTC3676EUJ#PBF QFN 40 E $7.86 $5.50 View
LTC3676EUJ#TRPBF QFN 40 E $5.56 View
LTC3676EUJ-1#PBF QFN 40 E $7.86 $5.50 View
LTC3676EUJ-1#TRPBF QFN 40 E $5.56 View
LTC3676HUJ#PBF QFN 40 H $9.43 $6.60 View
LTC3676HUJ#TRPBF QFN 40 H $6.66 View
LTC3676HUJ-1#PBF QFN 40 H $9.43 $6.60 View
LTC3676HUJ-1#TRPBF QFN 40 H $6.66 View
LTC3676IUJ#PBF QFN 40 I $9.07 $6.35 View
LTC3676IUJ#TRPBF QFN 40 I $6.41 View
LTC3676IUJ-1#PBF QFN 40 I $9.07 $6.35 View
LTC3676IUJ-1#TRPBF QFN 40 I $6.41 View
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
DC1976A-A LTC3676EUJ Demo Board | PMIC for Application Processors: 4 Bucks, 4 LDOs, I2C Control (req DC2026). $150.00
DC1976A-B LTC3676EUJ-1 Demo Board | PMIC with DDR DC/DC for Application Processors: 4 Bucks, 4 LDOs, I2C Control (req DC2026). Contact Factory
Buy Now

Companion Boards

Part Number Description Price Documentation
DC2026A Linduino One Isolated Arduino-Compatible Demonstration Board $75.00
Buy Now
Click here to view our complete list of demo boards

Applications

  • Supports Freescale i.MX6, ARM Cortex, and Other Application Processors
  • Handheld Instruments and Scanners
  • Portable Industrial and Medical Devices
  • Automotive Infotainment
  • High End Consumer Devices
  • Multi-Rail Systems

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

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 LTC3676 - DC1976A Linduino.INO File

/*
Linear Technology DC1976A Demonstration Board
LTC3676: Power Management Solution for Application Processors

@verbatim

NOTES
  Setup:
   Set the terminal baud rate to 115200 and select the newline terminator.
   External power supply is required. Any assembly option may be used: 
   DC1976A-A, DC1976A-B.

@endverbatim
 
http://www.linear.com/product/LTC3676

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

REVISION HISTORY
$Revision:  $
$Date:  $

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.
*/

#include 
#include 
#include "Linduino.h"
#include "UserInterface.h"
#include "LT_I2C.h"
#include "QuikEval_EEPROM.h"
#include "LTC3676.h"

// Function Declarations
int8_t menu_1_read_write_registers();
int8_t menu_2_regulator_settings();
int8_t menu_3_control_settings();
int8_t menu_4_sequencing(uint8_t *reg_phase);

void print_title();          
void print_prompt();          
void print_warning_prompt();  
int8_t LTC3676_print_all_registers(uint8_t i2c_address);
void read_reg_map(uint8_t *reg_map_array);

// Global variables
static uint8_t demo_board_connected;     //!< Set to 1 if the board is connected
static uint8_t i2c_address;              //!< I2C address set for either -A or -B demo board
static char board_option;                //!< Demo board option of the attached demo board
char demo_name[] = "DC1976";             //!< Demo Board Name stored in QuikEval EEPROM
uint8_t reg_phase[7] = {1,1,1,1,1,1,1};  //!< Power-up sequence phases for every regulator output
float delay_ms = 0;                      //!< Delay between power-up phases

//! Initialize Linduino
void setup()
{
  char eeprom_string[50];
  uint8_t char_count;
  quikeval_I2C_init();          //! Initializes Linduino I2C port.
  quikeval_I2C_connect();       //! Connects I2C port to the QuikEval connector
  Serial.begin(115200);         //! Initialize the serial port to the PC
  print_title();
  demo_board_connected = discover_demo_board(demo_name);  //! Checks if correct demo board is connected.  
  if (demo_board_connected)
  {
    
    char_count = read_quikeval_id_string(eeprom_string);
    board_option = demo_board_option(eeprom_string);
    if (board_option == 'B') i2c_address = LTC3676_1_I2C_ADDRESS;
    else i2c_address = LTC3676_I2C_ADDRESS;
    print_prompt();
  }  
  else
  {
    print_warning_prompt();
    demo_board_connected = true;
    i2c_address = LTC3676_I2C_ADDRESS;
  }
}

//! Repeats Linduino loop
void loop()
{
  int8_t ack=0;
  uint8_t user_command;
  if (demo_board_connected)                          //! Does nothing if the demo board is not connected
  {
    if (Serial.available())                          //! Checks for user input
    {
      user_command = read_int();                     //! Reads the user command
      if (user_command != 'm')
        Serial.println(user_command);
      ack = 0;
      switch (user_command)                               //! Prints the appropriate submenu
      {
        case 1:
          ack |= menu_1_read_write_registers();          // Print single-ended voltage menu
          break;
        case 2:
          ack |= menu_2_regulator_settings();            // Differential voltage menu
          break;
        case 3:
          ack |= menu_3_control_settings();              // Control Settings menu
          break;
        case 4:
          ack |= menu_4_sequencing(reg_phase);           // Sequencing menu
          break;
        default:
          Serial.println("Incorrect Option");
          break;
      }
      if (ack != 0)
      {
        Serial.print(F("Error: No Acknowledge. \n"));
      }
      print_prompt();
    }
  }  
}

// Function Definitions

//! Prints the title block when program first starts.
void print_title()
{
  Serial.print(F("\n*****************************************************************\n"));
  Serial.print(F("* DC1976A Demonstration Program                                 *\n"));
  Serial.print(F("*                                                               *\n"));
  Serial.print(F("* This program demonstrates how to send and receive data from   *\n"));
  Serial.print(F("* the LTC3676 Power Management Solution for                     *\n"));
  Serial.print(F("* Application Processors.                                       *\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()
{
  Serial.print(F("\n  1-Read/Write Registers\n"));
  Serial.print(F("  2-Regulator Settings\n"));
  Serial.print(F("  3-Control Settings\n"));
  Serial.print(F("  4-Sequencing\n"));
  Serial.print(F("\nEnter a command:"));
}

//! 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."));
}

int8_t LTC3676_print_all_registers(uint8_t i2c_address)
{
  int8_t ack = 0;
  uint8_t user_register = 0x01;
  uint8_t data;
  do
  {
    ack |= LTC3676_register_read(i2c_address, user_register, &data);   //! Read register
    Serial.print("Register 0x");
    Serial.print(user_register, HEX);
    Serial.print(":\t0x");
    Serial.println(data, HEX);
    user_register++;
  }
  while((user_register <= 0x17) && (ack != 1));
  return ack;
}

char demo_board_option(char *eeprom_string)
{
  char option='0';
  uint8_t i;
  for (i=0; i < strlen(eeprom_string); i++)
  {
    if (eeprom_string[i] == 'A' && option == '0')  
      option = eeprom_string[i+2];
  }
  return option;  
}

int8_t menu_1_read_write_registers()
{
  int8_t ack=0;
  uint8_t user_command;
  uint8_t data;
  uint8_t user_register;
  uint8_t user_bit;
  do
  {
    //! 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-Clear IRQ\n"));
    Serial.print(F("  7-Send Hard Reset Command\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 LTC3676 and prints result.
    switch (user_command)
    {
      case 1:
        // Read every register and print it's data.
        ack |= LTC3676_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 (user_register < 0x01 || user_register > 0x17)
        {
          Serial.println(F("  Invalid input."));
          break;
        }
        ack |= LTC3676_register_read(i2c_address, user_register, &data);
        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 (user_register == 0x1E)
        {
          Serial.println(F("  Hard Reset command sent."));
          ack |= LTC3676_register_write(i2c_address, user_register, 0x01);
          break;
        }
        else if (user_register == 0x1F)
        {
          Serial.println(F("  Clear IRQ command sent."));
          ack |= LTC3676_register_write(i2c_address, user_register, 0x01);
          break;
        }
        else if (user_register < 0x01 || user_register > 0x17)
        {
          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 |= LTC3676_register_write(i2c_address, user_register, data);
        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 (user_register < 0x01 || user_register > 0x17)
        {
          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 |= LTC3676_bit_set(i2c_address, user_register, data);
        Serial.print("Bit set. Register data is now 0x");
        ack |= LTC3676_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 (user_register < 0x01 || user_register > 0x17)
        {  
          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 |= LTC3676_bit_clear(i2c_address, user_register, data);
        Serial.print("Bit cleared. Register data is now 0x");
        ack |= LTC3676_register_read(i2c_address, user_register, &data);
        Serial.println(data, HEX); 
        break;
      case 6:
        // Clear IRQ register
        Serial.println(F("\n  Clear IRQ command sent."));
        ack |= LTC3676_register_write(i2c_address, LTC3676_REG_CLIRQ, 0x01);
        break;
      case 7:
        // Initiate a hard reset
        Serial.println(F("\n  Hard Reset command sent."));
        ack |= LTC3676_register_write(i2c_address, LTC3676_REG_HRST, 0x01);
        break;
      default:
        if (user_command != 'm')
          Serial.println("Invalid Selection");
        break;
    }
  }
  while ((user_command != 'm') && (ack != 1));
  return(ack);
}

int8_t menu_2_regulator_settings()
{
  int8_t ack=0;
  uint8_t user_command;
  uint8_t data;
  uint8_t user_register;
  uint8_t user_int;
  uint8_t user_buck;
  uint8_t user_ldo;
  int8_t user_char;
  do
  {
    //! Displays the Regulator Settings menu
    Serial.print(F("\nRegulator Settings\n\n"));
    Serial.print(F("  1-Enable/Disable Bucks\n"));
    Serial.print(F("  2-Enable/Disable LDOs\n"));
    Serial.print(F("  3-Set Buck Output Voltage\n"));
    Serial.print(F("  4-Set Buck Feedback Reference\n"));
    Serial.print(F("  5-Select Buck Reference\n"));
    Serial.print(F("  6-Set Buck Switching Mode\n"));
    Serial.print(F("  7-Set Start-Up Mode (300mV check)\n"));
    Serial.print(F("  8-Set PGOOD Slewing Mask\n"));
    Serial.print(F("  9-Exit Software Control Mode\n"));
    if (board_option == 'B')
      Serial.print(F("  10-Set LDO4 Output Voltage\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 LTC3676 and prints result.
    switch (user_command)
    {
      case 1:
        //Enter software control mode
        if(!LTC3676_bit_is_set(i2c_address, LTC3676_REG_CNTRL, LTC3676_SOFTWARE_CNTRL))
        {
          Serial.print(F("\n********** Note: LTC3676 is now in Sofware Control Mode **********\n"));
          Serial.print(F("***************Select Option 9 to resume Pin Control *************\n"));
          ack |= LTC3676_bit_set(i2c_address, LTC3676_REG_CNTRL, LTC3676_SOFTWARE_CNTRL); 
        }  
        // Enable/Disable Bucks
        Serial.print(F("\nSelect Buck(1-4, 5=all): "));
        user_buck = read_int();
        Serial.println(user_buck, DEC);
        if (user_buck < 1 || user_buck > 5)
        {
          Serial.println(F("  Invalid input."));
          break;
        }
        Serial.println(F("0=Disable, 1=Enable"));
        Serial.print(F("Enter selection: "));
        user_int = read_int();
        Serial.println(user_int, DEC);
        if (user_int > 1)
        {
          Serial.println(F("  Invalid input."));
          break;
        }
        if (user_int == 1)
          ack |= LTC3676_bit_set(i2c_address, LTC3676_REG_CNTRL, LTC3676_PWR_ON);
        if (user_buck == 5)
        {
          ack |= LTC3676_bit_write(i2c_address, LTC3676_REG_BUCK1, 7, user_int);
          ack |= LTC3676_bit_write(i2c_address, LTC3676_REG_BUCK2, 7, user_int);
          ack |= LTC3676_bit_write(i2c_address, LTC3676_REG_BUCK3, 7, user_int);
          ack |= LTC3676_bit_write(i2c_address, LTC3676_REG_BUCK4, 7, user_int);
        }  
        else
          ack |= LTC3676_bit_write(i2c_address, user_buck, 7, user_int);
        Serial.println(F("Done."));
        break;  
      case 2:
        //Enter software control mode
        if(!LTC3676_bit_is_set(i2c_address, LTC3676_REG_CNTRL, LTC3676_SOFTWARE_CNTRL))
        {
          Serial.print(F("\n********** Note: LTC3676 is now in Sofware Control Mode **********\n"));
          Serial.print(F("***************Select Option 8 to resume Pin Control *************\n"));
          ack |= LTC3676_bit_set(i2c_address, LTC3676_REG_CNTRL, LTC3676_SOFTWARE_CNTRL); 
        } 
        // Enable/Disable LDOs
        Serial.print(F("\nSelect LDO(2-4, 5=all): "));
        user_ldo = read_int();
        Serial.println(user_ldo, DEC);
        if (user_ldo < 2 || user_ldo > 5)
        {
          Serial.println(F("  Invalid input."));
          break;
        }
        Serial.println(F("0=Disable, 1=Enable"));
        Serial.print(F("Enter selection: "));
        user_int = read_int();
        Serial.println(user_int, DEC);
        if (user_int > 1)
        {
          Serial.println(F("  Invalid input."));
          break;
        }
        if (user_int == 1)
          ack |= LTC3676_bit_set(i2c_address, LTC3676_REG_CNTRL, LTC3676_PWR_ON);
        if (user_ldo == 5)
        {
          ack |= LTC3676_bit_write(i2c_address, LTC3676_REG_LDOA, 2, user_int);
          ack |= LTC3676_bit_write(i2c_address, LTC3676_REG_LDOA, 5, user_int);
          ack |= LTC3676_bit_write(i2c_address, LTC3676_REG_LDOB, 2, user_int);
        }  
        else if (user_ldo == 2)
          ack |= LTC3676_bit_write(i2c_address, LTC3676_REG_LDOA, 2, user_int);
        else if (user_ldo == 3)
          ack |= LTC3676_bit_write(i2c_address, LTC3676_REG_LDOA, 5, user_int);
        else if (user_ldo == 4)
          ack |= LTC3676_bit_write(i2c_address, LTC3676_REG_LDOB, 2, user_int);  
        Serial.println(F("Done."));
        break;      
      case 3:
        // Set buck output voltage in mV
        float user_output;
        float new_output;
        Serial.print(F("\nSelect Buck(1-4): "));
        user_int = read_int();
        Serial.println(user_int, DEC);
        if (user_int < 1 || user_int > 4)
        {
          Serial.println(F("Invalid input."));
          break;
        }
        Serial.print(F("Select Reference (A=DVB"));
        Serial.print(user_int, DEC);
        Serial.print(F("A, B=DVB"));
        Serial.print(user_int, DEC);
        Serial.print(F("B): "));
        user_char = read_char();
        Serial.write(user_char);
        if (user_char == 'A' || user_char == 'a')
          user_register = (user_int*2) + 8;    //Converts selection to appropriate register address.
        else if (user_char == 'B' || user_char == 'b')
          user_register = (user_int*2) + 9;    //Converts selection of appropriate register address.
        else
        {
          Serial.println(F("\nInvalid input."));
          break;
        } 
        Serial.print(F("\nPotential output voltage range: "));
        Serial.print(LTC3676_buck_vout_min(user_int), 0);
        Serial.print(F("mV to "));
        Serial.print(LTC3676_buck_vout_max(user_int), 0);
        Serial.print(F("mV."));
        Serial.print(F("\nNew output voltage in mV: "));
        user_output = read_float();
        Serial.println(user_output, 0);
        if (user_output < LTC3676_buck_vout_min(user_int) | user_output > LTC3676_buck_vout_max(user_int))
        {
          Serial.println(F("\nInvalid input."));
          break;
        }
        new_output = LTC3676_set_buck_output_voltage(i2c_address, user_register, user_output);
        Serial.print(F("Output voltage set to "));
        Serial.print(new_output, 0);
        Serial.println(F("mV."));
        Serial.print(F("New Feedback Reference Bits: 0x"));
        ack |= LTC3676_register_read(i2c_address, user_register, &data);
        Serial.println(data & 0x1F, HEX);
        break;
      case 4:
        // Set buck feedback reference voltage in mV
        float user_reference;
        float new_reference;
        Serial.print(F("\nSelect Buck(1-4): "));
        user_int = read_int();
        Serial.println(user_int, DEC);
        if (user_int < 1 || user_int > 4)
        {
          Serial.println(F("Invalid input."));
          break;
        }
        Serial.print(F("Select Reference (A=DVB"));
        Serial.print(user_int);
        Serial.print(F("A, B=DVB"));
        Serial.print(user_int);
        Serial.print(F("B): "));
        user_char = read_char();
        Serial.write(user_char);
        if (user_char == 'A' || user_char == 'a')
          user_register = (user_int*2) + 8;    //Converts selection to appropriate register address.
        else if (user_char == 'B' || user_char == 'b')
          user_register = (user_int*2) + 9;    //Converts selection of appropriate register address.
        else
        {
          Serial.println(F("\nInvalid input."));
          break;
        }  
        Serial.print(F("\nNew feedback reference input in mV (412.5-800): "));
        user_reference = read_float();
        Serial.println(user_reference);
        if (user_reference < 412.5 | user_reference > 800)
        {
          Serial.println(F("\nInvalid input."));
          break;
        }
        new_reference = LTC3676_set_buck_fb_ref(i2c_address, user_register, user_reference);
        Serial.print(F("Feedback reference input set to "));
        Serial.print(new_reference, 0);
        Serial.println(F("mV"));
        Serial.print(F("New Feedback Reference Bits: 0x"));
        ack |= LTC3676_register_read(i2c_address, user_register, &data);
        Serial.println(data & 0x1F, HEX);
        break;
      case 5: 
        // Select buck reference (A or B) 
        Serial.print(F("\nSelect Buck(1-4, 5=all): "));
        user_buck = read_int();
        Serial.println(user_buck, DEC);
        if (user_buck < 1 || user_buck > 5)
        {
          Serial.println(F("  Invalid input."));
          break;
        }
        Serial.print(F("Select Reference (A or B): "));
        user_char = read_char();
        Serial.write(user_char);
        if (user_char == 'A' || user_char == 'a' || user_char == 'B' || user_char == 'b')
        {
          if (user_buck == 5)
            ack |= LTC3676_select_buck_reference(i2c_address, 0xFF, user_char);
          else 
            ack |= LTC3676_select_buck_reference(i2c_address, user_buck, user_char);
          Serial.println(F("\nDone."));
          break;
        }  
        Serial.println(F("\n  Invalid input."));
        break;
      case 6:
        // Set buck switching mode 
        Serial.print(F("\nSelect Buck(1-4, 5=all): "));
        user_register = read_int();
        Serial.println(user_register, DEC);
        if (user_register < 1 || user_register > 5)
        {
          Serial.println(F("  Invalid input."));
          break;
        }
        Serial.print(F("Select mode (0=Pulse Skipping, 1=Burst, 2=Forced Continuous): "));
        user_int = read_int();
        Serial.println(user_int, DEC);
        if (user_int < 0 || user_int > 2)
        {
          Serial.println(F("  Invalid input."));
          break;
        }
        if (user_register == 5)
          ack |= LTC3676_set_buck_mode(i2c_address, 0xFF, user_int);
        else  
          ack |= LTC3676_set_buck_mode(i2c_address, user_register, user_int);
        Serial.println(F("Switching mode(s) set."));
        break;
      case 7:
        // Sets the startup mode for all bucks
        Serial.print(F("\nSelect Buck(1-4, 5=all): "));
        user_buck = read_int();
        Serial.println(user_buck, DEC);
        if (user_buck < 1 || user_buck > 5)
        {
          Serial.println(F("  Invalid input."));
          break;
        }
        Serial.println(F("0=Enable at any output voltage, 1=Enable only if output <300mV"));
        Serial.print(F("Enter selection: "));
        user_int = read_int();
        Serial.println(user_int, DEC);
        if (user_int < 0 || user_int > 1)
        {
          Serial.println(F("  Invalid input."));
          break;
        }
        if (user_buck == 5)
          ack |= LTC3676_set_startup_mode(i2c_address, 0xFF, user_int);
        else
          ack |= LTC3676_set_startup_mode(i2c_address, user_buck, user_int);
        Serial.println(F("Start-up mode(s) set."));
        break;
      case 8:
        // Sets PGOOD masks bit for all bucks.
        Serial.print(F("\nSelect Buck(1-4, 5=all): "));
        user_buck = read_int();
        Serial.println(user_buck, DEC);
        if (user_buck < 1 || user_buck > 5)
        {
          Serial.println(F("  Invalid input."));
          break;
        }
        Serial.println(F("0=PGOOD low when slewing, 1=PGOOD not forced low when slewing"));
        Serial.print(F("Enter selection: "));
        user_int = read_int();
        Serial.println(user_int, DEC);
        if (user_int < 0 || user_int > 1)
        {
          Serial.println(F("  Invalid input."));
          break;
        }
        if (user_buck == 5)
          ack |= LTC3676_set_buck_pgood_mask(i2c_address, 0xFF, user_int);
        else
          ack |= LTC3676_set_buck_pgood_mask(i2c_address, user_buck, user_int);
        Serial.println(F("PGOOD Mask bit(s) set."));
        break;
      case 9:
        // Exit software control mode
        ack |= LTC3676_bit_clear(i2c_address, LTC3676_REG_CNTRL, LTC3676_SOFTWARE_CNTRL);
        break;
      case 10:
        // Set LDO4 Output Voltage for DC1976A-B 
        if (board_option == 'B')
        {
          Serial.print(F("Select LDO4 Voltage (0=1.2V, 1=2.5V, 2=2.8V, 3=3.0V): "));
          user_int = read_int();
          Serial.println(user_int, DEC);
          if (user_int > 3)
          {
            Serial.println(F("  Invalid input."));
            break;
          }
          ack |= LTC3676_1_set_ldo4_voltage(i2c_address, user_int);
          Serial.println(F("LDO4 Voltage Set."));
          break;
        }
        Serial.println(" Invalid Selection");
        break;
      default:
        if (user_command != 'm')
          Serial.println(" Invalid Selection");
        break;  
    }
  }  
  while ((user_command != 'm') && (ack != 1));
  return (ack);    
}

int8_t menu_3_control_settings()
{
  int8_t ack=0;
  uint8_t user_command;
  uint8_t data;
  uint8_t user_register;
  uint8_t user_int;
  int8_t user_char;
  do
  {
    //! Displays the Control Settings menu
    Serial.print(F("\nControl Settings\n\n"));
    Serial.print(F("  1-Set UV Warning Threshold\n"));
    Serial.print(F("  2-Set Over-Temperature Warning Level\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 LTC3676 and prints result.
    switch (user_command)
    {
      case 1:
        // Set UV warning threshold
        float user_threshold;
        Serial.print(F("\nEnter new UV warning threshold in Volts (2.7 - 3.4): "));
        user_threshold = read_float();
        Serial.println(user_threshold, 1);
        if(user_threshold < 2.7 | user_threshold > 3.4)
        {
          Serial.println(F("Invalid input."));
          break;
        }
        ack = LTC3676_set_uv_warning_threshold(i2c_address, user_threshold);
        Serial.print(F("UV warning threshold set to "));
        Serial.print(user_threshold,1);
        Serial.println(F("V"));
        break;
      case 2:
        // Set over-temperature warning level
        Serial.print(F("Enter warning level in deg C below over-temperature shutdown(10,20,30,40): "));
        user_int = read_int();
        Serial.println(user_int, DEC);
        if(user_int < 10 | user_int > 40)
        {
          Serial.println(F("Invalid input."));
          break;
        }
        ack = LTC3676_set_overtemp_warning_level(i2c_address, user_int);
        Serial.print(F("Warning level set to "));
        Serial.print(((uint8_t)((user_int + 5)/10))*10);
        Serial.println(F("C below Over-temperature"));
        break;  
      default:
        if (user_command != 'm')
          Serial.println(" Invalid Selection");
        break;  
    }
  }  
  while ((user_command != 'm') && (ack != 1));
  return (ack);    
}


int8_t menu_4_sequencing(uint8_t *reg_phase)
{
  int8_t ack=0;
  uint8_t user_command;
  uint8_t data;
  uint8_t user_sequence;
  uint8_t user_int;
  uint8_t reg_map[6];
  uint8_t reg_address[7] = {1,2,3,4,5,5,6};
  uint8_t reg_bit_position[7] = {7,7,7,7,2,5,2};
  int count;
  
  //Enter software control mode
  if(!LTC3676_bit_is_set(i2c_address, LTC3676_REG_CNTRL, LTC3676_SOFTWARE_CNTRL))
  {
    Serial.print(F("\n********** Note: LTC3676 is now in Sofware Control Mode **********\n"));
    Serial.print(F("************** Select Option 8 to resume Pin Control *************\n"));
    ack |= LTC3676_bit_set(i2c_address, LTC3676_REG_CNTRL, LTC3676_SOFTWARE_CNTRL); 
  }  
  do
  {
    //! Displays the Startup Sequencing menu

    Serial.print(F("\nPowerup Sequencing\n\n"));
    Serial.print(F("  1-Set Power-up Sequence\n"));
    Serial.print(F("  2-Print Power-up Sequence\n"));
    Serial.print(F("  3-Set Buck Power-down Sequence\n"));
    Serial.print(F("  4-Set LDO Power-down Sequence\n"));  
    Serial.print(F("  5-Print Power-down Sequence\n"));
    Serial.print(F("  6-Power-up Regulators\n"));
    Serial.print(F("  7-Power-down Regulators\n"));
    Serial.print(F("  8-Exit Software Control Mode\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
    
    switch (user_command)
    {
      case 1: 
        Serial.println(F("\nRegulators will power-up in 4 phases"));
        Serial.println(F("Select a phase for each"));
        Serial.println(F("1=First phase, 2=Second phase, 3=Third phase, 4=Fourth phase, 0=Don't enable"));
        Serial.print(F("Buck1: "));
        user_int = read_int();
        Serial.println(user_int, DEC);
        if (user_int < 5)
          reg_phase[0] = user_int;
        Serial.print(F("Buck2: "));
        user_int = read_int();
        Serial.println(user_int, DEC);
        if (user_int < 5)
          reg_phase[1] = user_int;
        Serial.print(F("Buck3: "));
        user_int = read_int();
        Serial.println(user_int, DEC);
        if (user_int < 5)
          reg_phase[2] = user_int;
        Serial.print(F("Buck4: "));
        user_int = read_int();
        Serial.println(user_int, DEC);
        if (user_int < 5)
          reg_phase[3] = user_int;
        Serial.print(F("LDO2: "));
        user_int = read_int();
        Serial.println(user_int, DEC);
        if (user_int < 5)
          reg_phase[4] = user_int;
        Serial.print(F("LDO3: "));
        user_int = read_int();
        Serial.println(user_int, DEC);
        if (user_int < 5)
          reg_phase[5] = user_int;
        Serial.print(F("LDO4: "));
        user_int = read_int();
        Serial.println(user_int, DEC);
        if (user_int < 5)
          reg_phase[6] = user_int;
        Serial.print(F("Enter delay between phases in milliseconds: "));
        delay_ms = read_float();
        if (delay_ms >= 0 && delay_ms <= 10000)
          Serial.println(delay_ms, 1);
        else
          Serial.println(F("Values less than 0 or greater than 10s not allowed."));
        break;
      case 2:
        Serial.print(F("\nBuck1: "));
        Serial.println(reg_phase[0]);
        Serial.print(F("Buck2: "));
        Serial.println(reg_phase[1]);
        Serial.print(F("Buck3: "));
        Serial.println(reg_phase[2]);
        Serial.print(F("Buck4: "));
        Serial.println(reg_phase[3]);
        Serial.print(F("LDO2:  "));
        Serial.println(reg_phase[4]);
        Serial.print(F("LDO3:  "));
        Serial.println(reg_phase[5]);
        Serial.print(F("LDO4:  "));
        Serial.println(reg_phase[6]);
        Serial.print(F("Delay: "));
        Serial.print(delay_ms, 1);
        Serial.println(F("ms"));
        break;
      case 3:
        // Set Buck Power-down Sequence
        Serial.print(F("\nSelect Buck(1-4): "));
        user_int = read_int();
        Serial.println(user_int, DEC);
        if (user_int < 1 || user_int > 4)
        {
          Serial.println(F("Invalid input."));
          break;
        }
        Serial.println(F("0=with WAKE, 1=WAKE+100ms, 2=WAKE+200ms, 3=WAKE+300ms"));
        Serial.print(F("Enter selection: "));
        user_sequence = read_int();
        Serial.println(user_sequence, DEC);
        if (user_sequence > 3)
        {
          Serial.println(F("Invalid input."));
          break;
        }
        ack |= LTC3676_set_buck_sequence_down(i2c_address, user_int, user_sequence);
        Serial.print(F("Sequence down set for Buck"));
        Serial.println(user_int, DEC);
        break;
      case 4:
        // Set LDO Power-down Sequence
        Serial.print(F("\nSelect LDO(2-4): "));
        user_int = read_int();
        Serial.println(user_int, DEC);
        if (user_int < 2 || user_int > 4)
        {
          Serial.println(F("Invalid input."));
          break;
        }
        Serial.println(F("0=with WAKE, 1=WAKE+100ms, 2=WAKE+200ms, 3=WAKE+300ms"));
        Serial.print(F("Enter selection: "));
        user_sequence = read_int();
        Serial.println(user_sequence, DEC);
        if (user_sequence > 3)
        {
          Serial.println(F("Invalid input."));
          break;
        }
        ack |= LTC3676_set_ldo_sequence_down(i2c_address, user_int, user_sequence);
        Serial.print(F("Sequence down set for LDO"));
        Serial.println(user_int, DEC);
        break;  
      case 5:
        //Print power-down sequence
        ack |= LTC3676_register_read(i2c_address, LTC3676_REG_SQD1, &data);
        Serial.print(F("\nBuck1: "));
        Serial.println(data & LTC3676_BUCK1_SEQ_MASK, DEC);
        Serial.print(F("Buck2: "));
        Serial.println((data & LTC3676_BUCK2_SEQ_MASK)>>2, DEC);
        Serial.print(F("Buck3: "));
        Serial.println((data & LTC3676_BUCK3_SEQ_MASK)>>4, DEC);
        Serial.print(F("Buck4: "));
        Serial.println((data & LTC3676_BUCK4_SEQ_MASK)>>6, DEC);
        ack |= LTC3676_register_read(i2c_address, LTC3676_REG_SQD2, &data);
        Serial.print(F("LDO2:  "));
        Serial.println(data & LTC3676_LDO2_SEQ_MASK, DEC);
        Serial.print(F("LDO3:  "));
        Serial.println((data & LTC3676_LDO3_SEQ_MASK)>>2, DEC);
        Serial.print(F("LDO4:  "));
        Serial.println((data & LTC3676_LDO4_SEQ_MASK)>>4, DEC);
        Serial.print(F("Delay between phases(fixed): 100ms\n"));
        break;
      case 6:
        //Power-up regulators
        ack |= LTC3676_bit_set(i2c_address, LTC3676_REG_CNTRL, LTC3676_PWR_ON);
        delay(100);
        read_reg_map(reg_map);
        //Start Phase 1 Regulators
        ack |= LTC3676_register_write_start(i2c_address);
        for (count=0; count<7; count++)
        {
          if (reg_phase[count] == 1)
            ack |= LTC3676_register_write_subaddress_and_data(reg_address[count], ((0x01<

Download LTC3676 - Linduino Header File

/*!
LTC3676: Power management solution for application processors

@verbatim

The LTC3676 is a complete power management solution for advanced portable 
application processor-based systems. The device contains four synchronous 
step-down DC/DC converters for core, memory, I/O, and system on-chip (SoC) 
rails and three 300mA LDO regulators for low noise analog supplies. The 
LTC3676-1 has a 1.5A buck regulator configured to support DDR termination 
plus a VTTR reference output. An I2C serial port is used to control regulator 
enables, power-down sequencing, output voltage levels, dynamic voltage 
scaling, operating modes and status reporting.
Regulator start-up is sequenced by connecting outputs to enable pins in the 
desired order or via the I2C port. System power-on, power-off and reset 
functions are controlled by pushbutton interface, pin inputs, or I2C.
The LTC3676 supports i.MX, PXA and OMAP processors with eight independent 
rails at appropriate power levels. Other features include interface signals 
such as the VSTB pin that toggles between programmed run and standby output 
voltages on up to four rails simultaneously. The device is available in a 
40-lead 6mm x 6mm QFN package.

I2C DATA FORMAT (MSB FIRST);

@endverbatim

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

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

REVISION HISTORY
$Revision:  $
$Date: $

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 LTC3676
    Library Header File for LTC3676: Power management solution for application processors
*/

#ifndef LTC3676_H
#define LTC3676_H
#endif

/*! @name I2C_ADDRESSES
    I2C address of the LTC3676 and LTC3676-1.
@{ */
/* LTC3676 I2C Addresses */
#define LTC3676_I2C_ADDRESS         0x3C  
#define LTC3676_1_I2C_ADDRESS       0x3D  
/*! @} */

/*! @name FEEDBACK RESISTORS
    Feedback resistor values for the DC1976A-A in kOhm. 
@{ */
/* LTC3676 Registers */
#define LTC3676_RES_BUCK1_RTOP      1000.
#define LTC3676_RES_BUCK1_RBOT      280.
#define LTC3676_RES_BUCK2_RTOP      1000.
#define LTC3676_RES_BUCK2_RBOT      1100.
#define LTC3676_RES_BUCK3_RTOP      1000.
#define LTC3676_RES_BUCK3_RBOT      1100.
#define LTC3676_RES_BUCK4_RTOP      1000.
#define LTC3676_RES_BUCK4_RBOT      931.
/*! @} */

/*! @name REGISTERS
@{ */
/* LTC3676 Registers */
#define LTC3676_REG_BUCK1       0x01
#define LTC3676_REG_BUCK2       0x02
#define LTC3676_REG_BUCK3       0x03
#define LTC3676_REG_BUCK4       0x04
#define LTC3676_REG_LDOA        0x05
#define LTC3676_REG_LDOB        0x06
#define LTC3676_REG_SQD1        0x07
#define LTC3676_REG_SQD2        0x08
#define LTC3676_REG_CNTRL       0x09
#define LTC3676_REG_DVB1A       0x0A
#define LTC3676_REG_DVB1B       0x0B
#define LTC3676_REG_DVB2A       0x0C
#define LTC3676_REG_DVB2B       0x0D
#define LTC3676_REG_DVB3A       0x0E
#define LTC3676_REG_DVB3B       0x0F
#define LTC3676_REG_DVB4A       0x10
#define LTC3676_REG_DVB4B       0x11
#define LTC3676_REG_MSKIRQ      0x12
#define LTC3676_REG_MSKPG       0x13
#define LTC3676_REG_USER        0x14
#define LTC3676_REG_IRQSTAT     0x15
#define LTC3676_REG_PGSTATL     0x16
#define LTC3676_REG_PGSTATRT    0x17
#define LTC3676_REG_HRST        0x1E
#define LTC3676_REG_CLIRQ       0x1F
/*! @} */

/*! @name LTC3676_REG_BUCKx SETTINGS
    Bit position of single bit settings in the LTC3676_REG_BUCKx registers.
@{ */
#define LTC3676_BUCK_ENABLE          7
#define LTC3676_BUCK_STARTUP         4
#define LTC3676_BUCK_PHASE_SEL       3
#define LTC3676_BUCK_CLOCK_RATE      2
#define LTC3676_BUCK_KEEP_ALIVE      1
#define LTC3676_BUCK_SLEW            0
/*! @} */

/*! @name LTC3676_REG_LDOA SETTINGS
    Bit position of single bit settings in the LTC3676_REG_LDOA register.
@{ */
#define LTC3676_LDO3_ENABLE          5
#define LTC3676_LDO3_STARTUP         4
#define LTC3676_LDO3_KEEP_ALIVE      3
#define LTC3676_LDO2_ENABLE          2
#define LTC3676_LDO2_STARTUP         1
#define LTC3676_LDO2_KEEP_ALIVE      0
/*! @} */

/*! @name LTC3676_REG_LDOB SETTINGS
    Bit position of single bit settings in the LTC3676_REG_LDOB register.
@{ */
#define LTC3676_LDO4_ENABLE          2
#define LTC3676_LDO4_STARTUP         1
#define LTC3676_LDO4_KEEP_ALIVE      0
/*! @} */

/*! @name LTC3676_REG_CNTRL SETTINGS
    Bit position of single bit settings in the LTC3676_REG_CNTRL register.
@{ */
#define LTC3676_PWR_ON               7
#define LTC3676_PB_RESET_TMR         6
#define LTC3676_SOFTWARE_CNTRL       5
 /*! @} */

/*! @name LTC3676_REG_DVBxA SETTINGS
    Bit position of single bit settings in the LTC3676_REG_DVBxA registers.
@{ */
#define LTC3676_BUCK_REF_SELECT      5
/*! @} */

/*! @name LTC3676_REG_DVBxB SETTINGS
    Bit position of single bit settings in the LTC3676_REG_DVBxB register.
@{ */
#define LTC3676_BUCK_PG_MASK         5
/*! @} */

/*! @name LTC3676_REG_MSKIRQ SETTINGS
    Bit position of single bit settings in the LTC3676_REG_MSKIRQ register.
@{ */
#define LTC3676_MASK_OT_SHUTDOWN     6
#define LTC3676_MASK_OT_WARNING      5
#define LTC3676_MASK_UV_SHUTDOWN     4
#define LTC3676_MASK_UV_WARNING      3
#define LTC3676_MASK_PG_TIMEOUT      2
#define LTC3676_MASK_PB_STATUS       0
/*! @} */

/*! @name LTC3676_REG_MSKPG SETTINGS
    Bit position of single bit settings in the LTC3676_REG_MSKPG register.
@{ */
#define LTC3676_ENABLE_PG_LDO4       7
#define LTC3676_ENABLE_PG_LDO3       6
#define LTC3676_ENABLE_PG_LDO2       5
#define LTC3676_ENABLE_PG_BUCK4      3
#define LTC3676_ENABLE_PG_BUCK3      2   
#define LTC3676_ENABLE_PG_BUCK2      1
#define LTC3676_ENABLE_PG_BUCK1      0
/*! @} */

/*! @name LTC3676_REG_USER SETTINGS
    Bit position of single bit settings in the LTC3676_REG_USER register.
@{ */
#define LTC3676_USER_7               7
#define LTC3676_USER_6               6
#define LTC3676_USER_5               5
#define LTC3676_USER_4               4   
#define LTC3676_USER_3               3
#define LTC3676_USER_2               2   
#define LTC3676_USER_1               1
#define LTC3676_USER_0               0
/*! @} */

/*! @name LTC3676_REG_IRQSTAT SETTINGS
    Bit position of status bits in the LTC3676_REG_IRQSTAT register.
@{ */
#define LTC3676_IRQ_OT_SHUTDOWN      6
#define LTC3676_IRQ_OT_WARNING       5
#define LTC3676_IRQ_UV_SHUTDOWN      4   
#define LTC3676_IRQ_UV_WARNING       3
#define LTC3676_IRQ_PG_TIMEOUT       2  
#define LTC3676_IRQ_HARD_RESET       1
#define LTC3676_IRQ_PB_STATUS        0
/*! @} */

/*! @name LTC3676_REG_PGSTATL SETTINGS
    Bit position of status bits in the LTC3676_REG_PGSTATL register.
@{ */
#define LTC3676_PGL_LDO4             7
#define LTC3676_PGL_LDO3             6
#define LTC3676_PGL_LDO2             5
#define LTC3676_PGL_LDO1             4   
#define LTC3676_PGL_BUCK4            3
#define LTC3676_PGL_BUCK3            2   
#define LTC3676_PGL_BUCK2            1
#define LTC3676_PGL_BUCK1            0
/*! @} */

/*! @name LTC3676_REG_PGSTATRT SETTINGS
    Bit position of status bits in the LTC3676_REG_PGSTATRT register.
@{ */
#define LTC3676_PGRT_LDO4            7
#define LTC3676_PGRT_LDO3            6
#define LTC3676_PGRT_LDO2            5
#define LTC3676_PGRT_LDO1            4   
#define LTC3676_PGRT_BUCK4           3
#define LTC3676_PGRT_BUCK3           2   
#define LTC3676_PGRT_BUCK2           1
#define LTC3676_PGRT_BUCK1           0
/*! @} */

/*! @name LTC3676 MASK SETTINGS
    Bitwise AND with register data to determine present setting.
@{ */
#define LTC3676_BUCK_SEQ_MASK(num)  (0x03<<((num)*2)-2)
#define LTC3676_LDO_SEQ_MASK(num)   (0x03<<((num-2)*2))
#define LTC3676_BUCK_MODE_MASK       0x60
#define LTC3676_BUCK4_SEQ_MASK       0xC0
#define LTC3676_BUCK3_SEQ_MASK       0x30
#define LTC3676_BUCK2_SEQ_MASK       0x0C
#define LTC3676_BUCK1_SEQ_MASK       0x03
#define LTC3676_LDO4_SEQ_MASK        0x30
#define LTC3676_LDO3_SEQ_MASK        0x0C
#define LTC3676_LDO2_SEQ_MASK        0x03
#define LTC3676_UV_WARN_THRESH_MASK  0x1C
#define LTC3676_OT_WARN_LEVEL_MASK   0x03
#define LTC3676_FB_REF_MASK          0x1F
/*! @} */

/*! @name LTC3676-1 ONLY MASK SETTINGS
    Bitwise AND with register data to determine present setting.
@{ */
#define LTC3676_1_LDO4_VOLTAGE_MASK    0x18
/*! @} */

//! Reads an 8-bit register from the LTC3676 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 LTC3676_register_read(uint8_t i2c_address,       //!< I2C address of the LTC3676. 
                             uint8_t register_address,  //!< Address of the LTC3676 register to be read. This is also known as the "command byte".
                             uint8_t *register_data     //!< returns 8-bit value read from the LTC3676 register.
                            );

//! Writes to an 8-bit register inside the LTC3676 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 LTC3676_register_write(uint8_t i2c_address,      //!< I2C address of the LTC3676.
                              uint8_t register_address, //!< Address of the LTC3676 register to be overwritten.  This is also known as the "command byte".
                              uint8_t register_data     //!< Value that will be written to the register.
                             );
       
//! Writes an I2C Start and the LTC3676 I2C address.  
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTC3676_register_write_start(uint8_t i2c_address      //!< I2C address of the LTC3676.
                                   );
                                   
//! Writes a register subaddress and data to the LTC3676.  Can be called multiple times after a LTC3676_register_write_start call to update multiple registers simultaneously. 
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTC3676_register_write_subaddress_and_data(uint8_t subaddress,  //!< Address of the LTC3676 register to be overwritten.  This is also known as the "command byte".
                                                  uint8_t data         //!< Value that will be written to the register.
                                                 );
                          
//! Sets any bit inside the LTC3676 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 LTC3676_bit_set(uint8_t i2c_address,      //!< I2C address of the LTC3676. 
                       uint8_t register_address, //!< Address of the LTC3676 register to be overwritten.  This is also known as the "command byte".
                       uint8_t bit_number        //!< Bit location (0-7) to be written. 
                      );        
 
//! Clears any bit inside the LTC3676 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 LTC3676_bit_clear(uint8_t i2c_address,      //!< I2C address of the LTC3676.
                         uint8_t register_address, //!< Address of the LTC3676 register to be overwritten.  This is also known as the "command byte".
                         uint8_t bit_number       //!< Address of the bit to set within the register.
                        );                           
                        
//! Writes any bit inside the LTC3676 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 LTC3676_bit_write(uint8_t i2c_address,       //!< I2C address of the LTC3676.
                         uint8_t register_address,  //!< Address of the LTC3676 register to be written. 
                         uint8_t bit_number,        //!< Bit location (0-7) to be written. 
                         uint8_t bit_data           //!< Bit data (0 or 1) to be written.
                        ); 
                        
//! Reads the value of any bit in any register or the LTC3676.
//! @return Returns the bit value at the passed register subaddress and bit location.
uint8_t LTC3676_bit_is_set(uint8_t i2c_address,        //!< I2C address of the LTC3676.
                           uint8_t register_address,   //!< Address of the LTC3676 register to be read. This is also known as the "command byte".
                           uint8_t bit_number          //!< Bit location (0-7) to be read.
                          );
                        
//! Sets the output voltage of any buck. 
//! @return Returns the new buck output voltage, the closest allowable voltage to the user's chosen voltage.
float LTC3676_set_buck_output_voltage(uint8_t i2c_address, //!< I2C address of the LTC3676.
                                      uint8_t register_address, //!< Address of the LTC3676 Buck FB reference register to be written.
                                      float output_voltage //!< New output voltage to set, in mV. Assumes a valid voltage for the feedback resistors.
                                     );

//! Writes the Feedback Reference Voltage of any buck.
//! @return Returns the new Feedback Reference Input Voltage, the closest allowable voltage to the user's chosen voltage.
float LTC3676_set_buck_fb_ref(uint8_t i2c_address, //!< I2C address of the LTC3676.
                              uint8_t register_address, //!< Address of the LTC3676 Buck FB reference register to be written.
                              float fb_ref_voltage //!< New Feedback Reference voltage to set in mV.  Values between 412.5 and 800 are allowed.
                             );
                             
//! Calculates the maximum output voltage of any buck in mV based on the feedback resistors.
//! @return Returns the maximum possible output voltage for the selected buck.
float LTC3676_buck_vout_max(uint8_t buck_number //!< Number (1-4) of buck.
                           ); 
                           
//! Calculates the minimum output voltage of any buck in mV based on the feedback resistors.
//! @return Returns the minimum possible output voltage for the selected buck.
float LTC3676_buck_vout_min(uint8_t buck_number //!< Number (1-4) of buck.
                           ); 

//! Selects the reference for the specified buck regulator(s).
//! @return Returns the state of the acknowledge bit after the I2C addresss write. 0=acknowledge, 1=no acknowledge.
int8_t LTC3676_select_buck_reference(uint8_t i2c_address, //!< I2C address of the LTC3676.
                                     uint8_t buck_number, //!< Number (1-4) of the buck whose reference will be selected. Enter 0xFF for all bucks.
                                     int8_t ref_char //!< Reference to select (A or B).
                                    ); 

//! Sets the switching mode for the specified Buck regulator.
//! @return Returns the state of the acknowledge bit after the I2C addresss write. 0=acknowledge, 1=no acknowledge.
int8_t LTC3676_set_buck_mode(uint8_t i2c_address, //!< I2C address of the LTC3676.
                             uint8_t buck_number, //!< Number (1-4) of the buck to set. Enter 0xFF for all bucks.
                             uint8_t mode //!< Switching mode to be set (0=pulse skipping, 1=burst, 2=forced continuous)
                            );
                            
//! Sets the start-up mode for all bucks.
//! @return Returns the state of the acknowledge bit after the I2C addresss write. 0=acknowledge, 1=no acknowledge.
int8_t LTC3676_set_startup_mode(uint8_t i2c_address, //!< I2C address of the LTC3676.
                                uint8_t buck_number, //!< Number (1-4) of the buck to set. Enter 0xFF for all bucks.
                                uint8_t startup_bit //!< Data to write to start-up bit (0=enable at any output, 1=enable only if output <300mV)
                               );       

//! Sets the PGOOD mask bit in the DVBxB register for all bucks.
//! @return Returns the state of the acknowledge bit after the I2C addresss write. 0=acknowledge, 1=no acknowledge.
int8_t LTC3676_set_buck_pgood_mask(uint8_t i2c_address, //!< I2C address of the LTC3676.
                                   uint8_t buck_number, //!< Number (1-4) of the buck to set.
                                   uint8_t pgood_bit //!< Data to write to PGOOD bit (0=PGOOD low when slewing, 1=PGOOD not forced low when slewing)
                                  );                    

//! Writes a new UV warning threshold voltage in the CTRL register.
//! @return Returns the state of the acknowledge bit after the I2C addresss write. 0=acknowledge, 1=no acknowledge.
int8_t LTC3676_set_uv_warning_threshold(uint8_t i2c_address, //!< I2C address of the LTC3676.
                                        float uv_warning_threshold //!< New UV warning threshold to set, in volts.  Values between 2.7 and 3.4 are allowed.
                                       );                       

//! Writes the UV warning threshold of any buck.
//! @return Returns the state of the acknowledge bit after the I2C addresss write. 0=acknowledge, 1=no acknowledge.
int8_t LTC3676_set_overtemp_warning_level(uint8_t i2c_address, //!< I2C address of the LTC3676.
                                          uint8_t ot_warning_level //!< New overtemp warning level to set, degrees C below Overtemperature fault level.  Values 10, 20, 30, and 40 are allowed.
                                         );        

//! Sets LDO4 output voltage on the LTC3676-1.
//! @return Returns the state of the acknowledge bit after the I2C addresss write. 0=acknowledge, 1=no acknowledge.                                         
int8_t LTC3676_1_set_ldo4_voltage(uint8_t i2c_address, //!< I2C address of the LTC3676-1.
                                  uint8_t ldo4_output_voltage_code //!< Voltage code for new LDO4 output voltage: 0=1.2V, 1=2.5V, 2=2.8V, 3=3.0V
                                 );
                                 
//! Sets the Sequence Down bits for any buck in the SQD1 register.
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTC3676_set_buck_sequence_down(uint8_t i2c_address, //!< I2C address of the LTC3676.
                                      uint8_t buck_number, //!< Number (1-4) of the buck to sequence.  
                                      uint8_t sequence_phase //!< Sequence down phase: 0=with WAKE, 1=WAKE+100ms, 2=WAKE+200ms, 3=WAKE+300ms.
                                     );
                                     
//! Sets the Sequence Down bits for any buck in the SQD1 register.
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTC3676_set_ldo_sequence_down(uint8_t i2c_address, //!< I2C address of the LTC3676.
                                     uint8_t ldo_number, //!< Number (2-4) of the LDO to sequence.  
                                     uint8_t sequence_phase //!< Sequence down phase: 0=with WAKE, 1=WAKE+100ms, 2=WAKE+200ms, 3=WAKE+300ms.
                                    );                                     

Download LTC3676 - Linduino.CPP File

/*!
LTC3676: Power management solution for application processors

@verbatim

The LTC3676 is a complete power management solution for advanced portable 
application processor-based systems. The device contains four synchronous 
step-down DC/DC converters for core, memory, I/O, and system on-chip (SoC) 
rails and three 300mA LDO regulators for low noise analog supplies. The 
LTC3676-1 has a 1.5A buck regulator configured to support DDR termination 
plus a VTTR reference output. An I2C serial port is used to control regulator 
enables, power-down sequencing, output voltage levels, dynamic voltage 
scaling, operating modes and status reporting.
Regulator start-up is sequenced by connecting outputs to enable pins in the 
desired order or via the I2C port. System power-on, power-off and reset 
functions are controlled by pushbutton interface, pin inputs, or I2C.
The LTC3676 supports i.MX, PXA and OMAP processors with eight independent 
rails at appropriate power levels. Other features include interface signals 
such as the VSTB pin that toggles between programmed run and standby output 
voltages on up to four rails simultaneously. The device is available in a 
40-lead 6mm x 6mm QFN package.

I2C DATA FORMAT (MSB FIRST);

@endverbatim

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

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

REVISION HISTORY
$Revision:  $
$Date: $

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 LTC3676
    Library for LTC3676: Power management solution for application processors
*/

#include 
#include 
#include "Linduino.h"
#include "LT_I2C.h"
#include "LTC3676.h"

// Reads an 8-bit register from the LTC3676 using the standard repeated start format.
int8_t LTC3676_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);
}

// Writes to an 8-bit register inside the LTC3676 using the standard I2C repeated start format.
int8_t LTC3676_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);
}

//! Writes an I2C Start and the LTC3676 I2C address.  
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTC3676_register_write_start(uint8_t i2c_address)
{
  int8_t ack=0;
  i2c_start();
  ack |= i2c_write(i2c_address<<1);
  return(ack);
}
                                   
//! Writes a register subaddress and data to the LTC3676.  Can be called multiple times after a LTC3676_register_write_start call to update multiple registers simultaneously. 
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge. 
int8_t LTC3676_register_write_subaddress_and_data(uint8_t subaddress, uint8_t data)
{
  int8_t ack=0;
  ack |= i2c_write(subaddress); 
  ack |= i2c_write(data);
  return ack;
}

// Sets a bit within any register inside the LTC3676 using the standard I2C repeated start format.
int8_t LTC3676_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 |= LTC3676_register_read(i2c_address, register_address, ®ister_data);  //Read register
  register_data = register_data | bit_mask;  //Set the bit at bit_address
  ack |= LTC3676_register_write(i2c_address, register_address, register_data);  //Write new data to register
  return(ack);
}

// Sets a bit within any register inside the LTC3676 using the standard I2C repeated start format.
int8_t LTC3676_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 |= LTC3676_register_read(i2c_address, register_address, ®ister_data);  //Read register
  register_data = register_data & (~bit_mask);  //Clears the bit at bit_address
  ack |= LTC3676_register_write(i2c_address, register_address, register_data);  //Write new data to register
  return(ack);
}

//! Writes any bit inside the LTC3676 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 LTC3676_bit_write(uint8_t i2c_address, uint8_t register_address, uint8_t bit_number, uint8_t bit_data)
{
  uint8_t register_data;
  uint8_t bit_mask;
  int8_t ack = 0;
  bit_mask = 0x01 << bit_number;
  ack |= LTC3676_register_read(i2c_address, register_address, ®ister_data);  //Read register
  register_data = register_data & (~bit_mask);  //Clears the bit at bit_address
  register_data = register_data | ((bit_data & 0x01) << bit_number);  //Writes the new bit
  ack |= LTC3676_register_write(i2c_address, register_address, register_data);  //Write new data to register
  return(ack);
}  

//! Reads the value of any bit in any register or the LTC3676.
//! @return Returns the bit value at the passed register subaddress and bit location.
uint8_t LTC3676_bit_is_set(uint8_t i2c_address, uint8_t register_address, uint8_t bit_number)
{
  uint8_t register_data;
  int8_t ack = 0;
  ack |= LTC3676_register_read(i2c_address, register_address, ®ister_data);
  register_data = register_data >> bit_number;  //Clears everything but the bit of interest
  return (register_data & 0x01);
}

//! Sets the output voltage of any buck.
float LTC3676_set_buck_output_voltage(uint8_t i2c_address, uint8_t register_address, float output_voltage)
{
  uint8_t register_data;
  float fb_ref = 0;
  int8_t nack = 0;
  if (register_address == 0x0A | register_address == 0x0B)
  {
    fb_ref = output_voltage / (1 + LTC3676_RES_BUCK1_RTOP/LTC3676_RES_BUCK1_RBOT);  //Generates desired FB reference input for given output voltage.
    return (1 + LTC3676_RES_BUCK1_RTOP/LTC3676_RES_BUCK1_RBOT) * LTC3676_set_buck_fb_ref(i2c_address, register_address, fb_ref);  //Writes new buck output fb refernce.
  }
  if (register_address == 0x0C | register_address == 0x0D)
  {
    fb_ref = output_voltage / (1 + LTC3676_RES_BUCK2_RTOP/LTC3676_RES_BUCK2_RBOT);  //Generates desired FB reference input for given output voltage.
    return (1 + LTC3676_RES_BUCK2_RTOP/LTC3676_RES_BUCK2_RBOT) * LTC3676_set_buck_fb_ref(i2c_address, register_address, fb_ref);  //Writes new buck output fb refernce.
  }
  if (register_address == 0x0E | register_address == 0x0F)
  {
    fb_ref = output_voltage / (1 + LTC3676_RES_BUCK3_RTOP/LTC3676_RES_BUCK3_RBOT);  //Generates desired FB reference input for given output voltage.
    return (1 + LTC3676_RES_BUCK3_RTOP/LTC3676_RES_BUCK3_RBOT) * LTC3676_set_buck_fb_ref(i2c_address, register_address, fb_ref);  //Writes new buck output fb refernce.
  }
  if (register_address == 0x10 | register_address == 0x11)
  {
    fb_ref = output_voltage / (1 + LTC3676_RES_BUCK4_RTOP/LTC3676_RES_BUCK4_RBOT);  //Generates desired FB reference input for given output voltage.  
    return (1 + LTC3676_RES_BUCK4_RTOP/LTC3676_RES_BUCK4_RBOT) * LTC3676_set_buck_fb_ref(i2c_address, register_address, fb_ref);  //Writes new buck output fb refernce.
  }
}
                        
//! Writes the Feedback Reference Voltage of any buck.
//! @return Returns the new Feedback Reference Input Voltage, the closest allowable voltage to the user's chosen voltage.
float LTC3676_set_buck_fb_ref(uint8_t i2c_address, uint8_t register_address, float fb_ref_voltage)
{
  uint8_t register_data;
  uint8_t fb_ref_data = 0;
  int8_t nack = 0;
  fb_ref_data = (uint8_t) ((fb_ref_voltage + 6.25 - 412.5) / 12.5);  //Generates 5-bit code for closest allowable value to user's chosen reference voltage.
  nack |= LTC3676_register_read(i2c_address, register_address, ®ister_data); //Read current register value
  register_data = register_data & (~LTC3676_FB_REF_MASK); //Clears existing feedback reference bits
  register_data = register_data | fb_ref_data;
  nack |= LTC3676_register_write(i2c_address, register_address, register_data);  //Writes new register value
  return (412.5 + (fb_ref_data * 12.5)); 
}

//! Calculates the maximum output voltage of any buck in mV based on the feedback resistors.
//! @return Returns the maximum possible output voltage for the selected buck.
float LTC3676_buck_vout_max(uint8_t buck_number)
{
  switch (buck_number)
  {
    case 1:
      return ((1 + (LTC3676_RES_BUCK1_RTOP/LTC3676_RES_BUCK1_RBOT)) * 800);
      break;
    case 2:
      return ((1 + (LTC3676_RES_BUCK2_RTOP/LTC3676_RES_BUCK2_RBOT)) * 800);
      break;
    case 3:
      return ((1 + (LTC3676_RES_BUCK3_RTOP/LTC3676_RES_BUCK3_RBOT)) * 800);
      break;
    case 4:
      return ((1 + (LTC3676_RES_BUCK4_RTOP/LTC3676_RES_BUCK4_RBOT)) * 800);
      break;  
  }
}

//! Calculates the minimum output voltage of any buck in mV based on the feedback resistors.
//! @return Returns the minimum possible output voltage for the selected buck.
float LTC3676_buck_vout_min(uint8_t buck_number)
{
  switch (buck_number)
  {
    case 1:
      return ((1 + LTC3676_RES_BUCK1_RTOP/LTC3676_RES_BUCK1_RBOT) * 412.5);
      break;
    case 2:
      return ((1 + LTC3676_RES_BUCK2_RTOP/LTC3676_RES_BUCK2_RBOT) * 412.5);
      break;
    case 3:
      return ((1 + LTC3676_RES_BUCK3_RTOP/LTC3676_RES_BUCK3_RBOT) * 412.5);
      break;
    case 4:
      return ((1 + LTC3676_RES_BUCK4_RTOP/LTC3676_RES_BUCK4_RBOT) * 412.5);
      break;  
  }
} 

//! Selects the reference for the specified buck regulator(s).
//! @return Returns the state of the acknowledge bit after the I2C addresss write. 0=acknowledge, 1=no acknowledge.
int8_t LTC3676_select_buck_reference(uint8_t i2c_address, uint8_t buck_number, int8_t ref_char)
{
  uint8_t user_register;
  int8_t ack = 0;
  if (buck_number == 0xFF)
  {
      ack |= LTC3676_select_buck_reference(i2c_address, 1, ref_char);
      ack |= LTC3676_select_buck_reference(i2c_address, 2, ref_char);
      ack |= LTC3676_select_buck_reference(i2c_address, 3, ref_char);
      ack |= LTC3676_select_buck_reference(i2c_address, 4, ref_char);
      return(ack);
  }  
  user_register = (buck_number*2) + 8;  //Converts selection to appropriate register address.
  if (ref_char == 'A' || ref_char == 'a')
    ack |= LTC3676_bit_clear(i2c_address, user_register, 5);
  else if (ref_char == 'B' || ref_char == 'b')
    ack |= LTC3676_bit_set(i2c_address, user_register, 5);
  return(ack);
}

//! Sets the switching mode for the specified Buck regulator.
//! @return Returns the state of the acknowledge bit after the I2C addresss write. 0=acknowledge, 1=no acknowledge.
int8_t LTC3676_set_buck_mode(uint8_t i2c_address, uint8_t buck_number, uint8_t mode)
{
  uint8_t register_data;
  int8_t ack = 0;
  if (buck_number == 0xFF)
  {
    ack |= LTC3676_set_buck_mode(i2c_address, 0x01, mode);
    ack |= LTC3676_set_buck_mode(i2c_address, 0x02, mode);
    ack |= LTC3676_set_buck_mode(i2c_address, 0x03, mode);
    ack |= LTC3676_set_buck_mode(i2c_address, 0x04, mode);  
    return(ack);  
  }
  ack |= LTC3676_register_read(i2c_address, buck_number, ®ister_data);  //Read register
  register_data = register_data & (~LTC3676_BUCK_MODE_MASK);  //Clears the Mode bits in the Buck register
  register_data = register_data | (mode << 5);
  ack |= LTC3676_register_write(i2c_address, buck_number, register_data);  //Writes new register value
  return(ack);
}  

//! Sets the start-up mode for all bucks.
//! @return Returns the state of the acknowledge bit after the I2C addresss write. 0=acknowledge, 1=no acknowledge.
int8_t LTC3676_set_startup_mode(uint8_t i2c_address, uint8_t buck_number, uint8_t startup_bit)
{
  int8_t ack = 0;
  if (buck_number == 0xFF)
  {
    ack |= LTC3676_bit_write(LTC3676_I2C_ADDRESS, LTC3676_REG_BUCK1, LTC3676_BUCK_STARTUP, startup_bit);
    ack |= LTC3676_bit_write(LTC3676_I2C_ADDRESS, LTC3676_REG_BUCK2, LTC3676_BUCK_STARTUP, startup_bit);
    ack |= LTC3676_bit_write(LTC3676_I2C_ADDRESS, LTC3676_REG_BUCK3, LTC3676_BUCK_STARTUP, startup_bit);
    ack |= LTC3676_bit_write(LTC3676_I2C_ADDRESS, LTC3676_REG_BUCK4, LTC3676_BUCK_STARTUP, startup_bit);
    return(ack);
  }
  ack |= LTC3676_bit_write(LTC3676_I2C_ADDRESS, buck_number, LTC3676_BUCK_STARTUP, startup_bit);
  return(ack);
}     

//! Sets the PGOOD mask bit in the DVBxB register for all bucks.
//! @return Returns the state of the acknowledge bit after the I2C addresss write. 0=acknowledge, 1=no acknowledge.
int8_t LTC3676_set_buck_pgood_mask(uint8_t i2c_address, uint8_t buck_number, uint8_t pgood_bit)
{
  int8_t ack = 0;
  uint8_t dvbxb_register = (2*buck_number)+9;
  if (buck_number == 0xFF)
  {
    ack |= LTC3676_bit_write(LTC3676_I2C_ADDRESS, LTC3676_REG_DVB1B, LTC3676_BUCK_PG_MASK, pgood_bit);
    ack |= LTC3676_bit_write(LTC3676_I2C_ADDRESS, LTC3676_REG_DVB2B, LTC3676_BUCK_PG_MASK, pgood_bit);
    ack |= LTC3676_bit_write(LTC3676_I2C_ADDRESS, LTC3676_REG_DVB3B, LTC3676_BUCK_PG_MASK, pgood_bit);
    ack |= LTC3676_bit_write(LTC3676_I2C_ADDRESS, LTC3676_REG_DVB4B, LTC3676_BUCK_PG_MASK, pgood_bit); 
    return(ack);
  }
  ack |= LTC3676_bit_write(LTC3676_I2C_ADDRESS, dvbxb_register, LTC3676_BUCK_PG_MASK, pgood_bit);
  return(ack);
}  

//! Writes a new UV warning threshold voltage in the CTRL register.
//! @return Returns the state of the acknowledge bit after the I2C addresss write. 0=acknowledge, 1=no acknowledge.
int8_t LTC3676_set_uv_warning_threshold(uint8_t i2c_address, float uv_warning_threshold)
{
  int8_t ack = 0;
  uint8_t uv_warning_data = 0;
  uint8_t register_data;
  ack |= LTC3676_register_read(i2c_address, LTC3676_REG_CNTRL, ®ister_data);  //Read CNTRL register
  register_data = register_data & (~LTC3676_UV_WARN_THRESH_MASK);  //Clears the UV Warning Threshold bits in the CNTRL register
  uv_warning_data = (uint8_t) ((uv_warning_threshold + 0.05 - 2.7) / 0.1);  //Generates 3-bit code for closest allowable value to user's chosen threshold voltage.
  register_data = register_data | (uv_warning_data << 2);
  ack |= LTC3676_register_write(i2c_address, LTC3676_REG_CNTRL, register_data);  //Writes new register value
  return(ack);
}  

//! Writes the UV warning threshold of any buck.
//! @return Returns the state of the acknowledge bit after the I2C addresss write. 0=acknowledge, 1=no acknowledge.
int8_t LTC3676_set_overtemp_warning_level(uint8_t i2c_address, uint8_t ot_warning_level)
{
  int8_t ack = 0;
  uint8_t ot_warning_data = 0;
  uint8_t register_data;
  ack |= LTC3676_register_read(i2c_address, LTC3676_REG_CNTRL, ®ister_data);  //Read CNTRL register
  register_data = register_data & (~LTC3676_OT_WARN_LEVEL_MASK);  //Clears the over temperature warning level bits in the CNTRL register
  ot_warning_data = (uint8_t) ((ot_warning_level + 5 - 10) / 10);  //Generates 2-bit code for closest allowable value to user's chosen threshold voltage.
  register_data = register_data | ot_warning_data;
  ack |= LTC3676_register_write(i2c_address, LTC3676_REG_CNTRL, register_data);  //Writes new register value
  return(ack);
}  

//! Sets LDO4 output voltage on the LTC3676-1.
//! @return Returns the state of the acknowledge bit after the I2C addresss write. 0=acknowledge, 1=no acknowledge.                                         
int8_t LTC3676_1_set_ldo4_voltage(uint8_t i2c_address, uint8_t ldo4_output_voltage_code)
{
  int8_t ack = 0;
  uint8_t register_data;
  ack |= LTC3676_register_read(i2c_address, LTC3676_REG_LDOB, ®ister_data);  //Read register
  register_data = register_data & (~LTC3676_1_LDO4_VOLTAGE_MASK);  //Clears the LDO4 Output Voltage bits in the LDOB register
  register_data = register_data | (ldo4_output_voltage_code << 3);
  ack |= LTC3676_register_write(i2c_address, LTC3676_REG_LDOB, register_data);  //Writes new register value
  return(ack);
}  

//! Sets the Sequence Down bits for any buck in the SQD1 register.
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTC3676_set_buck_sequence_down(uint8_t i2c_address, uint8_t buck_number, uint8_t sequence_phase)
{
  int8_t ack = 0;
  uint8_t register_data;
  sequence_phase = sequence_phase & (0x03); //Mask out everything but the first two bits of sequence_phase
  ack |= LTC3676_register_read(i2c_address, LTC3676_REG_SQD1, ®ister_data);  //Read SQD1 register.
  register_data &= (~LTC3676_BUCK_SEQ_MASK(buck_number)); //Clear data in sequence down bits to be written.
  register_data |= (sequence_phase << ((buck_number*2)- 2)); //Bit shift sequence bits to the correct position.
  ack |= LTC3676_register_write(i2c_address, LTC3676_REG_SQD1, register_data); //Write new sequence data.
  return(ack);
}

//! Sets the Sequence Down bits for any buck in the SQD1 register.
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTC3676_set_ldo_sequence_down(uint8_t i2c_address, uint8_t ldo_number, uint8_t sequence_phase)
{
  int8_t nack = 0;
  uint8_t register_data;
  sequence_phase = sequence_phase & (0x03); //Mask out everything but the first two bits of sequence_phase
  nack |= LTC3676_register_read(i2c_address, LTC3676_REG_SQD2, ®ister_data);  //Read SQD2 register.
  register_data &= (~LTC3676_LDO_SEQ_MASK(ldo_number)); //Bit shift sequence bits to the correct position.
  register_data |= (sequence_phase << ((ldo_number-2)* 2)); //Bit shift sequence bits to the correct position.
  nack |= LTC3676_register_write(i2c_address, LTC3676_REG_SQD2, register_data); //Write new sequence data.
  return(nack);
}

Technical Support