Quad-SMU
AD5522 Based 4 Channel Parameter Source Measure Unit

The Blog for this project (not yet)

The Schematics, PCB files, and Simulation models are here (not yet)
Youtube Video on this project (not yet)

Introduction

As I discuss in the DIY-SMU project, SMUs are really useful. But really expensive. Evan a low voltage SMU is expensive. How about a 4 channel, low voltage SMU for about $250 parts cost? Analog Devices AD5522 to the rescue. Analog calls it a PMU (Parametric Measurement Unit) and it is typically used for IC DC parametric testing.  Since it has bipolar, 4 quadrant current and voltage source, With current and voltage measure capability, I call it an SMU. This IC is a 4 channel, 4 quadrant SMU with the following capabilities:
How does it differ from other SMUs?
What would you do with such a thing?
Here is the AD5522 Quad SMU IC block diagram from Analog Devices, showing just one channel.

ad5522-1


At Teradyne in 2007-2008 I was hardware lead on a DPS or Device Power supply product. This beast was a 256 channel(!!!), liquid-cooled,  power supply with independent DACs and ADCs for each channel. It used 256 of another Analog Devices IC, the AD5560, a single channel Device Power Supply (DPS). This part is similar in architecture to the AD5522. I became very familiar with the AD5560. These 2 parts share a similar architecture: several 16b DACs, current and voltage ranging, power stages and similar current ranging.

The AD5522 IC  is available with two package options: Pad-up and Pad-down. It is also available on two evaluation board, one for each package. At this time (10/2024) Mouser has 133 pad-up boards and 7pad-down in stock. Digikey has no  Eval boards in stock. Digikey has about 100 of each of the ICs. Mouser has 900 pad-up ICs and a few pad-down. 

I have one of the AD5522 pad-down eval boards. I tested it with the ADI evaluation software, and it works well. I came up with a PC board design that uses an eval board. Most of the required pins are available on various headers. A few additional wires, headers and modifications may need to be soldered to the eval board. 

The AD5522 has the following on-chip:
The evaluation board adds the following:
The carrier board and enclosure requires the following:

The rules about using and buying evaluation boards are more restrictive than other (SparkFun, Adafruit, Ali Express...) boards. Evaluation boards built by semiconductor companies are designed and intended for protyping and evaluation purposes only, and are not for building products for sale. These are sometimes loss-leaders, meaning that they are sold at a loss in order to help engineers design in their devices. Quantity purchases are usually limited to a few units per month. Building DIY products is somewhere in the grey zone, and unless you try to buy more than a few per month, shouldn't be a problem. Now that the ICs are readily available, and if this thing takes off, I would build a proper board around the IC and eliminate the eval board.
Here is the EVAL-AD5522EBD (D for down) Eval board.

    ad5522
          eval

Design

Since the core functionality of the SMU is defined by the AD5522, the project has some hardware, but is mostly firmware development

Here is the block diagram for the proposed system:
block

Control

For SPI data isolation. I like the Silicon Labs Si86xx series parts. For this design the 6 channel part with 5 signals in one direction and one return signal will do: Si8661.

Power

The power needs of this project are minimal. About 50 milliamps of +/- 15V per channel, and a watt of +5V. I'm leaning towards a clean, linear, supply using a 10W AC split-core transformer to minimize common mode noise.
A 15 or 20V to 5V DC-DC to provide he grounded +5V for the CPU and display.

Enclosure

Here is a possible layout in a Hammond Clamshell box, 1598D, about 8"x7"x2.4". The AD5522 eval board is below the main board and so is hidden. The +/- 15V power supply goes in the empty space. The front and rear panels would be custom designed sheet metal and built by PCBWay or other PCB manufacturer. The LCD is a Nextion 320x240 touch screen. Encoder knobs and buttons would mount above the I/O connectors.

case1 

CPU

For the CPU I haven't decided yet. It needs nothing special: USB, SCPI library, Fan control, a serial port for the Nextion display, EEPROM for Cal.  A basic Arduino could do the job, but would likely run out of memory,  Currently am considering one of the SAMD21's like the Adafruit ItsyBitsy M0 at $12. If Teensy is used, the 4.x is the only available one, about $24.

I really like the Adafruit SAMD21's, but unfortunately, there is no EEPROM. The available EEPROM Flash libraries do work, but do NOT retain EEPROM contents when flashing a new program. This is pretty useless if the  calibration process needs to be repeated every time you make a simple program change. For now I'll just store cal factors manually like I do for DIY-SMU. Or If I build a PC board, I'll add a small I2C EEPROM to it.

Display

There is a fair amount of stuff to display, lots of parameters. So I plan to use a 480x320 TFT LCD.  Leaning towards Nextion to get easy touch.

Firmware

The ADI GUI software that comes with the eval kit works well. Unfortunately, like most eval board software, it comes with no source code, no .DLL, and no way to use it other than with the the GUI provided. And no source code for the Cypress embedded processor either. So you are on your own to create the low level and high level code to control this very complex IC. Oh well. At least I can hook up a logic analyzer to the SPI bus to see what the register bangs are, in case I get stuck. Better than nothing. I'll quit whining and start coding.

In addition to lots of low level and calibration code needed, here are the user controls:
Here are the screens:

Calibration

There is a lot to calibrate: 5 current ranges and 1 voltage range on each of the 4 channels, source and measure, offset and gain, and maybe clamps. That's 4 x (5+1) x 2 x 2 = 96 cal factors, not including Clamps and Compares. I plan to use the same approach I used on DIY-SMU. An HP34401A DMM and some precision resistors, with a Python program to run it all. I'm experimenting with a semi-manual cal process: Adjust the cals for each channel and range and then store to EEPROM.

The good news is that there are provisions on the AD5522 chip to output each channel to a master measurement system for calibration. That should minimize the amount of external manual or automatic switching needed. These are the SYS_FORCE and SYS_SENSE signals on the IC.

SAMD21 processors don't have EEPROM, you use a small block of the processor's Flash memory instead and a separate library is needed. I'm trying the FlashStorage_SAMD library. It has EEPROM emulation functions.

SCPI Control

For SCPI control, I plan to follow the DIY-SMU project and use the https://github.com/Vrekrer/Vrekrer_scpi_parser library. Force and clamp settings for all channels, measure I and V for all channels. Temperature monitoring.

10/2024 Update

I got the evaluation board working again, and tested some of the features. I was able to hand-calibrate a couple of voltage outputs. Using a logic analyzer (LA1010), I could view the SPI transactions on the Eval board. I dug into the register descriptions, and was able to understand most of the bit fields. I wrote some Arduino code to drive the IC over SPI, and after a day or so of coding and troubleshooting, was able to get reliable control. The Eval board had the LVDS termination jumpers installed. But they didn't interfere with the Evaluation board even though it wasn't using LVDS. But the Arduino didn't like them installed.  I'm currently using an Adafruit ItsyBitsy M0 module. Getting Arduino working required:

The OLED and barometer module are just there to test I2C and to see if the SPI OLED interferes with the AD5522. So far so good.

bboard

The initialization for the AD5522 only needs a few 32 bit numbers to set up the System Control Register (SCR), the 4 PMU registers, and Force Voltage DAC registers. Conveniently, the 4 channels can be programmed either all at once, individually, or in any combination. Without any calibration, the outputs are pretty accurate. Less than 20mV offset and +/- 0.2% gain on the +/- 10V range.

I'm working on the carrier board design and layout. It will contain the processor module, isolation, power conditioning, and four output connectors. But first I want to implement code for the basic SPI, HW features and the ADC.

I struggled with the SPI interface to the AD5522 for a while. The AD5522 uses most of its parameters as direct register bangs. there is one PMU register per channel, containing about 10 settings for ranges, Mode, Measure, Enable and other stuff. I tried to use readback of the bits but SPI readback isn't simple and is time consuming. I decided to just shadow the 29 bit registers in a simple array: unsigned long PMU[4]. Just set the bits you want in the shadow, and write the register to the IC.

ADC: AD7685

I got the ADC on the Eval board working with Arduino. It is  a 16 bit, 250KHz, AD7685. I was able to get it converting, but all the returned values were 1/2 what I expected.  Turns out the 16bit ADC needs 17 bit SPI! The first bit (MSB) is not used. I considered just using 15 bits, but the 17th clock is needed to turn off the MOSI buffer, which is important. Dang ADI with their non-standard SPIs! So I read another 8 bits and just use the MSB.  If you use 4 wire SPI, it can handle 16 bits. But the AD5522 Eval board has SDI on the ADC (MOSI) hard wired to +5V, so gotta use 17 bits! I wrote this ugly code to get "accurate" current readings on the 2mA range only. The constants are the ADC readings at 0 current (10.0V, no load) and at 1mA (10.0V, 10K load).

  adc = ADCGetMeasure(0, 0);
  current = 0.001 * (adc - 29525) / (42620.0 - 29525.0);
  Serial.println(current, 7);

I was getting big ADC errors on occasional readings, about 20,000 codes. The errors occurred about once per minute at 5S/S.  After a bit of troubleshooting (trying random SPI things) I noticed the ADC timing on the scope would occasionally jump. The ADC timing was more time-critical than I thought, and did not like the various system interrupts delaying its timing. I added
noInterrupts() before and interrupts() after. Evil glitches fixed! Here is the ADC code. No channel or source yet, just raw ADC.

/* ADCGetMeasure()
 Read AD7685 ADC on eval board.
  Unfortunately with SDI = HI, 17 clocks are required to get all 16 bits.
  The first 15 bits are shifted up 1, then the 16th bit added in.
*/
unsigned short ADCGetMeasure(void){
  unsigned short spiRData;
  unsigned char lsb;
  noInterrupts();   // critical, time-sensitive code here
  digitalWrite(ADC_CNV, HIGH);
  digitalWrite(ADC_CNV, LOW);
  spiRData = SPI.transfer16( 0 );     // Get 15b data from ADC
  lsb = SPI.transfer( 0 );     // Get lsb, 17 clocks needed
  interrupts();
  lsb = (lsb >> 7) & 0x01;
  spiRData = (spiRData << 1) | lsb;
  return spiRData ;
}

BTW plotting the ADC data out using Arduino's serial plotter is a great tool for finding ADC errors. Noise, glitches, whatever.

When I wrote the code that selects the channel and  function to be measured, it controls the PMU[]:MEAS[1:0] bits on all 4 channels. With one fast ADC:

3 PMU registers can be written with the same data, but unfortunately there are other PMU settings that need to be maintained. So each register must be written one at a time. This significantly slows down the ADC when any channel or source is changed. If you want the ADC to go fast, don't change channels or sources. This could be sped up considerably by using either an external 4-input mux for the ADC, or an ADC with a built-in mux.

The ADC read time (24 bits) is about 20uS, with SPI clock of 4MHz. The 4 PMU 32 bit writes add about 30uS per write so about 140uS. So without changing the channel, the ADC is 1 / 20uS = 50KHz. With, it's about 7KHz. Not terrible. Shouldn't affect ADC averaging much, since averaging reads several values from the same channel.

When I first measured both current and voltage, I saw about a 10-15% error. I suspected crossstalk since reading one value was accurate. Error was traced to the ADC input changing just as the convert pulse was applied. I added about 10uS delay to the AD5522 control after changing setup to address this. 

First test data

I plotted one channel's Vout (VF) and VM. VF is measured with HP 44401A DMM, VM is from the AD7685 ADC. Clearly the force function works very well and the ADC has issues. Fond memories of the DIY-SMU ADC non-linearity. But I found the problem. Big duh!! The +5V power supply was adjusted down to about 4.6V. The ADC couldn't deal with its +5.00V reference above the power supply, and was causing those 10mV errors. With the power supply at +5.1V, the ADC and DAC errors combined are all under 1mV, so about 3LSBs. Nice!

The ADC noise is low: with 128 averaging ADC, the ADC noise is about 200uV p-p on 22V (+/- 11V) ADC, so about 9ppm. I'll generate new plots.

data1


EEPROM issue

I've never done calibration into EEPROM. This project with 4 channels is about 4x the calibration complexity of my last DIY-SMU. The AD5522 has offset and gain registers for it's Force, Clamp and Compare DACs.

I started with some simple examples using the EEPROM library. I designed how to map the many cal factors for many ranges, force, clamp and measure, and 4 channels into the EEPROM and how to manage (calculate)
addresses. When I tried to store stuff in EEPROM. I learned the hard way that SAMD21 has no EEPROM! There are libraries that emulate EEPROM in Flash, and I tried these. Unfortunately, re-flashing the program erases the emulated EEPROM! Totally useless! Some CPU's programming chains do this, some don't. What a pain! I decided to add a little AT24C08, 1Kx8, I2C EEPROM, about $0.40, so I wouldn't have to mess with the various processor differences. It has the other advantage that the calibration factors can be physically on the instrument, not just on the CPU.

Here is the list of remaining tasks for this project.

Evaluation and Arduino Code
*    SPI Details
*    Basic Force V
*    Current range settings
*    Basic ADC Measure current
*    ADC channel and source

    20-50mA range
*    ADC basic calibrations
*    Data structures
    Force I mode
    Clamps
    System connects
    Guard and sense

*    Manual Calibration of VF
    Manual Calibration of IF
*    Manual Calibration of VM
*   Manual Calibration of IM
 
    Auto-cal of everything 
    Save Cal to EEPROM
   
Finish PCB design:
   
Layout Eval board, connectors
    Layout carrier board

CPU controls:
    I/O Connections
    Mechanical for Eval
    Power conditioning
    Isolation
    Status LEDs
    Encode rand button connects
    Nextion serial port
    I2C EEPROM for calibration

Firmware:

    Controls: encoder(s) and buttons
    Basic Nextion display
    Advanced Nextion
    SCPI
    Alarms, Temperature....

Calibration
for all ranges, all channels:
    Force I / V
    Measure I/V
    Clamp I / V
    External Python or embedded code??
    
Mechanical
    Heat Sink (isolated)
    Case base plate
    Power Supply
    Front panel PCB
    Front panel
    Rear panel



  Dave's Home Page

Last Updated: 11/15/2024