Linduino PSM

Linduino PSM

Author's Contact Information

Michael Jones

Michael Jones

While many engineers use a dongle and tools to configure Power System Management devices via PMBus, a growing number of designs are adding Board Management Controllers, or connecting their PMBus to an existing microcontroller or application processer. At LTC, the dongle/tool option is comprised of a DC1613 and LTpowerPlay, and firmware development is supported with Linduino for Power System Management, aka “Linduino PSM.”

The Linduino platform is an isolated Arduino-compatible board (DC2026), code libraries for different devices, and sketches. Until recently, the focus was on I2C and SPI. Now there is support for PMBus devices, including a DC2294 shield, which allows an engineer to connect Linduino to PSM demo boards, and well as connect to a Total Phase Beagle for spying on the bus.

The goal of Linduino PSM is the same as the goal of Linduino in general, which is to provide working sample code so that engineers can learn, prototype, and borrow working code for their own designs.

Figure 1. DC2294 Shield on DC2026 Linduino

Linduino PSM PMBus Stack

The PMBus library provided by Linduino PSM is layered much like a network API. Layers allow substitution and replacement. For example, the driver layer could be reworked for an engineer’s final solution so that the layers on top of it can be reused without modification.

Figure 2. PMBus Library Stack

TWI and Wire Layers

At the bottom is the Two Wire Interface, which is a modified copy of the Arduino TWI and the LT_Wire libraries. The modifications are minimal, but solve a problem with block commands.

The SMBus 1.3 specification defines two block commands: Block Write and Block Read.

Figure 3. Block Write

Figure 4. Block Read

The byte count is allowed to range from 0 to 255 bytes. The Arduino versions of TWI and Wire only allowed 32 bytes. To support 255 byte transactions, three problems had to be solved:

  1. Small buffer
  2. Memory Usage
  3. API

The buffer has to hold up to 255 bytes (the original buffer was 32), but a large buffer will use 1/8th of the processor’s memory, even if the block calls are never used. The modified library passes the buffer into the API from the application. If the application allocates the memory, it only has to use memory when needed and can free it when not in use. The modified API can pass a value greater than 255 in order to transfer more than 255 bytes, because the count parameter was changed from a byte to a word.

LTC_I2CBus Layer

The LTC_I2CBus layer provides an I2C transaction interface. The original Linduino libraries came with another I2C library called LT_I2C. However, it was optimized around a different byte order and for DACs, ADCs, etc. By providing an I2C layer specifically for PMBus, the new layer can be maintained without updating older sketches or worrying about breaking other non-PSM sketches.

LTC_SMBus Layer

The LTC_SMBus layer provides the standard transactions for SMBus, which is the basis for PMBus. For example:

  • SendByte
  • Write/Read Byte
  • Write/Read Word
  • Write/Read Block

This layer can be used to communicate with any SMBus device, or to communicate with PMBus devices using PMBus command codes.

LTC_PMBus Layer

The LTC_PMBus layer provides high-level transactions based on the PMBus command set. This allows the engineer to program with high-level functions like:

  • Set Page
  • Read Current
  • Read Voltage
  • Sequence Up/Down

Using the higher layer commands makes code more readable, and the engineer does not have to look up commands in the specification. Some commands are aggregates, such as “set voltage for page N,” or “set voltage and keep margins the same percentage.”

If a command is missing, it is common practice to first code it using the LTC_SMBus layer, then to migrate the code to the LTC_PMBus layer.


PMBus uses data formats (L11/L16), that are not industry standards like IEEE 754 Float Point Standard, but engineer’s prefer the IEEE standards because C/C++ use this standard. The Linduino PSM library includes conversion routines to and from IEEE floating point and PMBus formats. The LTC_PMBus Layer accepts and returns IEEE floating point and manages the conversions within the layer using the LTC_PMBusMath routines. However, it is possible to use the math routines with the LTC_SMBus Layer.

Note: PMBus 1.3 defines an IEEE 754 format, but until the industry implements devices to this standard, the conversion routines in the math library will be required. There will also always be legacy devices to support.

Linduino Sketches

Linduino/Arduino Sketches are nothing more than small applications. For PSM, these are simple text menu applications that demonstrate features of a device, such as:

  1. Reading telemetry
  2. Reading status
  3. Sequencing up/down
  4. Probing the bus
  5. Dumping fault logs

Figure 5. Command Interface

The code behind them uses the LT_PMBus Layer, so the code is simple to read. The code below simply loops on a page, reads the voltage, and prints it in decimal format. The value from readOut is returned as a float, which is the IEEE 754 value; the conversion with the math library takes place in the read VOUT function.

void print_all_voltages()

float voltage;
uint8_t page;

for (page = 0; page < 2; page++)

pmbus->setPage(ltc3880_i2c_address, page);
voltage = pmbus->readVout(ltc3880_i2c_address, false);
voltage = pmbus->readVout(ltc3880_i2c_address, false);
Serial.println(voltage, DEC);

PEC is handled behind the scenes. On the main menu, PEC can be turned on and off. Because commands are written pmbus->, the pointer can be changed.

Figure 6. Main Menu

case 2:
  delete smbus;
  delete pmbus;
  smbus = new LT_SMBusPec();
  pmbus = new LT_PMBus(smbus);

case 3:
  delete smbus;
  delete pmbus;
  smbus = new LT_SMBusNoPec();
  pmbus = new LT_PMBus(smbus);

Well, almost. The devices must also be in the proper mode. The basic strategy is:

  1. Change device mode
  2. Delete the smbus and pmbus object
  3. Re-instance the objects with the proper mode

The code that uses the smbus-> and pmbus-> pointers does not have to change.

Other libraries (non-Linduino) pass a value to control PEC or configure a global variable. The Linduino approach uses C++ classes. However, the code is kept very simple so that it can be turned into pure C very quickly if the engineer is prohibited from using C++. Most embedded systems support C and C++ compilers, but if a large system is pure C, the engineer may not want to hassle with the C++ name mangling, or the effects of compiling C with a C++ compiler.


Prototyping is simply a matter of copying a sketch to a file with a new name and modifying it. Once a prototype is complete, the engineer must decide how to migrate the code to a final application.

If there is no legacy code involved, the simplest case is to rewrite the LTC_I2CBus or LTC_SMBus Layer and reuse the layers above it. If there is a lot of legacy code, it might be better to copy the prototype design and recode it. The main thing is the engineer can prototype in a simpler environment.

Hardware can also be reused. It is certainly possible to put an Atmega328 in a design and use the Linduino PSM code directly. Or with a few tweaks to the TWI/LTC_I2CBus an engineer could use one of the larger Arduino platforms. LTC ported these to the Galileo as an experiment and it took less than a day.

For slave hardware, the Linduino can be connected to any PSM demo board. However, most product designs have a connector for a DC1613 dongle, so the Linduino can be connected directly to an end design using the DC2294 Shield. This is a good way to prototype on a full design before committing resources on a new product. Algorithms can be developed for an operating system to determine how much computational power and memory space are required, and to prove it will offer a return on investment.

Tool Building

Linduino is a good platform for building specialized end-use tools. By combining Linduino, a DC2294, and off-the-shelf shields, one can create standalone tools. For example, the tool below is a programming tool that configures the non-volatile memory of a device in a hand socket. The up/down buttons select the file, and the SELECT button programs the device.

Figure 7. Example Tool

Educational Use

A final common use for Linduino PSM is learning. If the SMBus/PMBus standards are unfamiliar, a good way to learn is to connect a Total Phase Beagle, run some sketches on a DC1962, and observe the bus using the Total Phase Datacenter software. Note there is also an alternative, where LTpowerPlay can be used with a Beagle. LTpowerPlay has the advantage that the register syntax is built into the tool, so any value in the GUI can be displayed as an SMBus/PMBus transaction.


Linduino PSM is a prototyping, tool building, and learning environment for PMBus code development. The Linduino is combined with a DC2294 for connectivity to any PSM demo board or product. There is a complete working SMBus/PMBus library along with math conversions, compatible with the Arduino coding environment.

For more information on Linduino click here: Linduino solutions page.

For more information about power system design look through the other blogs click here: Power System Management Design.