SPI transfer

I have 3 things that I need to clarify:

  1. I have a MC33HB2001 chip which I wish to set at a 10.7 current limit when I start using it. I want to use an arduino mega's SPI as the master to interface with the chip. However, I am not too sure about the order of things I should send to the chip, and how I should go about sending the commands to the chip since arduino is 8 bit and the chip is 16 bit. Here is the code I have come up with so far:
#include <SPI.h> //SPI library
#define SS 10 // define slave select pin here

const uint16_t limit = 58256; // 1110001110010000 is the 16 bit that fits my specification 

SPISettings chip(10000000, MSBFIRST, SPI_MODE0); // 10MHz, MSB first, output on falling, data capture on rising

void setup() {

pinMode(SS,OUTPUT); //setting slave select pin as a digital output
SPI.begin();  //initialise SPI bus
digitalWrite(SS,LOW); //contact MC33HB2001
SPI.transfer16(limit); // send the 16 bits over
digitalWrite(SS,HIGH); //end contact with chip


void loop() {

other portion of code that is not related to chip


I want to ask if I have to just send the 16 bits over once to the chip and that is the end of story, or must I keep running the commands in the arduino loop()?

  1. For the MC33HB2001 chip, to send commands to it, do I just send a single 16 bit transmission, or must I do things in this order:

  2. Send a 'Write' command 16 bit

  3. Send my specific 'current limit' 16 bit

  4. End transmission

  5. Under the MC33HB2001 documentation, for the 'control and configuration', if i set bit 2 (active INPUT control mode) to 0, does this mean that bit 1 (virtual input 1) and bit 0 (virtual input 2) can be any value since I am not using virtual input to control my chip?

First, italic is not the way to post code, please edit your post to use code-tags. See How to use the forum.

Second, SPI has the function tranfer16() so the 16-bit registers on a device are not a problem.

And a tip, use more descriptive variable names. Things like limit and chip are so vague. Limit of what? What chip?

const uint16_t limit = 58256; // 1110001110010000 is the 16 bit that fits my specification

If it's more clear in binary, why not put it there in binary?

const uint16_t limit = 0b1110001110010000; // is the 16 bit that fits my specification

This also removes the value from the comment. This is a good idea because if you change the value and forget to change the comment you just get weird things.

  1. How would the driver know when the loop() ended or started? You just tell it once and as long as the MC33HB2001 is power it will keep that setting.

But before you can transfer data to the chip you need to call beginTransaction() in which you provide the SPIsettings as parameter, then do the transfer and after that free things again with endTransaction().

  1. If a transfer is a read or write is fully determined by bit 15 of the transfer. What to read/write is determined by bit 14 and bit 13 and the data is in the rest. So you just need to do a single transfer16() but in the order as in 1).

  2. Not sure because I just scanned the datasheet but it seems so, yes.

Hi septilion, thank you for your reply, appreciate the time and effort you did to help me with this.

Taking your advice in order, I presume my code should look like this:

#include <SPI.h> //SPI library
#define SS 10 // define slave select pin

const uint16_t current_limit_bit = 0b1110001110010000; // the configuration bit to program the MC33HB2001

void setup() {

pinMode(SS, OUTPUT); //setting slave select pin as digital output

SPI.beginTransaction(SPIsettings(10000000, MSBFIRST, SPI_MODE0)); // initialise SPI bus with 10MHz, MSB first, output on falling, data capture on rising
digitalWrite(SS,LOW); //contact MC33HB2001
SPI.transfer16(current_limit_bit); //transfer 16 bit command to MC33HB2001
digitalWrite(SS,HIGH); //end contact MC33HB2001
SPI.endTransaction(); // free SPI contact with chip 


void loop(){ 

non-related code


Just one more thing: if I were to have multiple MC33HB2001 chips (same SPI settings) to be run one after another, I simply have to follow my previous code except to have additional digitalWrite(SS, LOW), transfer16(current_limit_bit), digitalWrite(SS, HIGH) to each chip before endTransaction() correct?

Function wise, yes.

Code wise, mm.

Where is the indentation? It's one of the most important aids for you to spot errors...

It was not wrong to put the SPIsettings in a variable. Only give it a sensible name.

SS is already defined in Arduino. Besides, try to use the safe alternative to define instead. I would also give it a better name.

const byte MotorDriverSSPin = 10; //or just SSPin if you really only have 1 SPI device

Talking about names, current_limit_bit. The_variable_name_style might be your style, that's fine (as long as you stick to it) but note it's more commonToDoThis. Also, it's NOT only setting the current limit, it's setting all parameters. So that name is misleading. motor_driver_setting would cover it more.

And for multiple, yes. But of course every chip needs a separate SS pin (also called CS (ChipSelect) pin) which can't be all called SS. And instead of copy pasting it would make sense to put things in an array and loop it.

const byte CsPins[8, 9, 10];
const SPIsettings SpiSettingsMotorDriver(10000000, MSBFIRST, SPI_MODE0)

for(byte i = 0; i < sizeof(CsPins); i++){
  digitalWrite(CsPins[i], LOW); //contact MC33HB2001
  SPI.transfer16(MotorDriverSettings); //transfer 16 bit command to MC33HB2001
  digitalWrite(CsPins[i], HIGH); //end contact MC33HB2001
  SPI.endTransaction(); // free SPI contact with chip

BUT a thing you don't do now, is setting the pin HIGH after making it an input. After making it an input SS is already low. Not a problem because it's the only SS pin now, but for multiple be SURE to make them all high before looping over them all.

Alright, thank you very much for the advice!