MAX22200
Recommended for New Designs
The MAX22200/MAX22200A are octal 36V serial-controlled solenoid drivers. Each channel features a low impedance (200mΩ typ) push-pull output stage with...
Datasheet
MAX22200 on Analog.com
Hello,
I am trying to read MAX22200 Serial-Controlled Solenoid and Motor Driver data with spi communication. I ran into a few problems and frankly, I couldn't find many examples on the internet so I wanted to ask here.
When I examined the datasheet, I read that I had to send the Command Register to the sensor first and then write data or read data.

For example, when I energize, I want to read the STATUS Register Address(0x00) data of the sensor. I am sending 0x80 by SDI as Command Register.

In order to be able to read 32-bit data after the data, I send 0x00 by SDI, since no information is given on the datasheet side, I read 0x00 by SDO.
The question mark point stuck in my head here is actually when I change any bit of the STATUS Register, I still read 0x00.
Topics on my mind,
I had some difficulties understanding controlling this solenoid driver myself, but I created the following sketch in Arduino and I was able to turn solenoids on and off. It is very basic, and I just created this to make sure I understand the operating sequence. Next, I have to create some functions to clean this up, but I hope this helps to understand the sequence:
#include <SPI.h>
#define pin_csb 7 // Change this to your chip select pin
#define pin_en 8 // Change this to your enable pin
#define pin_cmd 9 // Change this to your command pin
byte response;
void setup() {
Serial.begin(115200);
delay(500); // delay required to connect to Serial
Serial.println("Initiated");
pinMode(pin_csb, OUTPUT);
pinMode(pin_en, OUTPUT);
pinMode(pin_cmd, OUTPUT);
digitalWrite(pin_csb, HIGH); // Keep CS high till SPI is required (chip select)
digitalWrite(pin_en, HIGH); // Enable the device
digitalWrite(pin_cmd, LOW);
SPI.begin();
SPI.beginTransaction(SPISettings(5000000, MSBFIRST, SPI_MODE0));
Serial.print("\nInitiated\nResponse from COMMAND register: ");
digitalWrite(pin_cmd, HIGH);
delayMicroseconds(50);
digitalWrite(pin_csb, LOW);
response = (SPI.transfer(0x00), BIN); // Read = 0, Status register 0x00, use 8MSB = 0
digitalWrite(pin_csb, HIGH);
delayMicroseconds(50);
digitalWrite(pin_cmd, LOW);
Serial.println(response, BIN);
delay(100);
Serial.print("Response from STATUS register: ");
digitalWrite(pin_csb, LOW);
response = SPI.transfer(0x00);
digitalWrite(pin_csb, HIGH);
Serial.println(response, BIN); // Read the status register
Serial.println("\nWrite status register to device activation");
Serial.print("Response from COMMAND register: ");
digitalWrite(pin_cmd, HIGH);
digitalWrite(pin_csb, LOW);
response = SPI.transfer(0x80); // write = 1, Status register 0x00, use 8MSB = 1
digitalWrite(pin_csb, HIGH);
digitalWrite(pin_cmd, LOW);
Serial.println(response, BIN);
Serial.print("Response from writting to STATUS register: ");
digitalWrite(pin_csb, LOW);
response = SPI.transfer(0x01); // Read the status register
SPI.transfer(0x00);
SPI.transfer(0x00);
SPI.transfer(0x00);
digitalWrite(pin_csb, HIGH);
Serial.println(response, BIN);
delay(100);
Serial.println("\nRead status register for UVM");
Serial.print("Response from COMMAND register: ");
digitalWrite(pin_cmd, HIGH);
digitalWrite(pin_csb, LOW);
response = SPI.transfer(0x00); // Read = 0, Status register 0x00, use 8MSB = 0
digitalWrite(pin_csb, HIGH);
digitalWrite(pin_cmd, LOW);
Serial.println(response, BIN);
Serial.print("Response from STATUS register: ");
digitalWrite(pin_csb, LOW);
SPI.transfer(0x00); // Read the status register (32 bits)
SPI.transfer(0x00); // Read the status register (32 bits)
SPI.transfer(0x00); // Read the status register (32 bits)
response = SPI.transfer(0x00); // Read the status register (32 bits), and safe status
digitalWrite(pin_csb, HIGH);
Serial.println(response, BIN);
delay(100);
Serial.println("\nRead again status register to clear UVM");
Serial.print("Response from COMMAND register: ");
digitalWrite(pin_cmd, HIGH);
digitalWrite(pin_csb, LOW);
response = SPI.transfer(0x00); // Read = 0, Status register 0x00, use 8MSB = 0
digitalWrite(pin_csb, HIGH);
digitalWrite(pin_cmd, LOW);
Serial.println(response, BIN);
Serial.print("Response from STATUS register: ");
digitalWrite(pin_csb, LOW);
SPI.transfer(0x00); // Read the status register (32 bits)
SPI.transfer(0x00); // Read the status register (32 bits)
SPI.transfer(0x00); // Read the status register (32 bits)
response = SPI.transfer(0x00); // Read the status register (32 bits), and safe status
digitalWrite(pin_csb, HIGH);
Serial.println(response, BIN);
}
void loop() {
delay(1000);
Serial.println("\nTurn on the solenoid on channel 0&1");
Serial.print("Response from COMMAND register: ");
digitalWrite(pin_cmd, HIGH);
digitalWrite(pin_csb, LOW);
response = SPI.transfer(0x80); // write = 1, Status register 0x00, use 8MSB = 0
digitalWrite(pin_csb, HIGH);
digitalWrite(pin_cmd, LOW);
Serial.println(response, BIN);
Serial.print("Response from STATUS register: ");
digitalWrite(pin_csb, LOW);
SPI.transfer(0x01); // Write the status register active
SPI.transfer(0x00); // Read the status register
SPI.transfer(0x00); // Read the status register
response = SPI.transfer(0x03); // Write the status register with Channel 0&1
digitalWrite(pin_csb, HIGH);
Serial.println(response, BIN);
delay(1000);
Serial.println("\nTurn off the solenoid on channel 0&1");
Serial.print("Response from COMMAND register: ");
digitalWrite(pin_cmd, HIGH);
digitalWrite(pin_csb, LOW);
response = SPI.transfer(0x80); // write = 1, Status register 0x00, use 8MSB = 0
digitalWrite(pin_csb, HIGH);
digitalWrite(pin_cmd, LOW);
Serial.println(response, BIN);
Serial.print("Response from STATUS register: ");
digitalWrite(pin_csb, LOW);
SPI.transfer(0x01); // Write the status register with active
SPI.transfer(0x00);
SPI.transfer(0x00);
response = SPI.transfer(0x00); // Write the status register with 0 to turn off all channels
digitalWrite(pin_csb, HIGH);
Serial.println(response, BIN);
}
Some comments:
You wrote that you sent 0x80 to the command register to read the status register, but you should be sending 0x00 instead. Sending 0x80 tells the command register that your next action is writing to the status register. Can you confirm that when you are writing to the status register, the command register is set up properly?
Hi!
I also spent a lot of time getting the communication between a stm32 nucleo board and the MAX22200 to work. I found a project on github with drivers for the chip and used them as a starting point. Basically I just adapted the style and functions to suit my project and added and removed functions as needed. Maybe it can help others too.
Here is the link: https://github.com/mentee-robotics/Hand6Motors/blob/main/Core/Src/max22200_driver.c
Regards
Lars
Have you managed to get proper return values from the MAX chip? I'm using an stm32 controller and can also turn channels on and off but can't seem to get real return values. I also just tried your arduino sketch since I had an ESP32 board here but then I also only get a UVM flag at start and aftere that only zeroes or ffff.
Regards
Lars
Apparently since last week there is an official driver available here: https://github.com/analogdevicesinc/no-OS/tree/master/drivers/digital-io/max22200
A bit annoying that it's still not mentioned anywhere else on the site.
If you can write to the IC but the read data is not available, one reason could be that you did not connect a pull-up resistor (300-360 ohm) to 3.3v from the MISO pin of the eval board. You need to do this as the pin is open-drain.
BR.
Hi!
Yes that turned out to be the problem. The reason was that when using an stm32 nucleo board doing the setup in CubeMX, it can often happen that when changing something in the CubeIDE and then generating the code again, the internal pullups or pulldowns disappear.
So always check this or as you said, use external pullups.
Regards
Lars