MMC5983 with SPI - Can't seem to line up clock and first bit

Hi all,

I am currently trying to use a DUE board and SPI with an MMC5983MA magnetometer (data sheet linked below). Using an analog discovery 2, I was able to see the binary readout that I was sending to the chip, and it matched what I was trying to send, but it seemed that the first bit was not in sync with the clock so I believe the chip is not getting the correct binary byte. I searched around and found articles on how to use the chip with I2C, but can't seem to figure out how to use it with SPI. I am using a MMC5983MA-B breakout board to make things easier (data sheet linked below).

MMC5983MA:

MMC983MA-B:

Here is the code that I am using:

#include <SPI.h>

const byte READ = 0b11000000;
const byte WRITE = 0b00000000; 

#define XOUT_0        0x00
#define XOUT_1        0x01
#define YOUT_0        0x02
#define YOUT_1        0x03
#define ZOUT_0        0x04
#define ZOUT_1        0x05
#define XYZOUT_2      0x06
#define TOUT          0x07
#define STATUS        0x08
#define CONTROL_0     0x09
#define CONTROL_1     0x0A
#define CONTROL_2     0x0B
#define CONTROL_3     0x0C
#define PRODUCT_ID    0x2F

const int chipSelectPin = 23; 
bool configured = false; 

void setup() {

  // Initialize pins
  pinMode(chipSelectPin, OUTPUT); 
  Serial.begin(9600);
  
  // Start SPI Library
  SPI.begin();

  // Setup SPI communication
  SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE3)); 
  
}

void loop() {
  // put your main code here, to run repeatedly:

  

  // Configure chip
  if (configured == false){
    writeRegister(CONTROL_1, 0b10000000); // Reset chip and set bandwidth to 8ms, 100Hz
    writeRegister(CONTROL_2, 0b00001010); // Enable continuous measurement and set frequency to 10Hz
    Serial.println("Configured"); 
    configured = true; 
  }

  // Allow sensor time to setup 
  delay(100); 

  // Attempt to read Product ID
  int data = readRegister(PRODUCT_ID, 1);
  Serial.print("I AM "); Serial.print(data); Serial.print(" I should be "); Serial.println(0x30, HEX);

  
  //Serial.println(data,BIN); 
//  SPI.endTransaction();
  delay(500); 

}

// Read from MMC5983MA
unsigned int readRegister(byte thisRegister, int bytesToRead){

  unsigned int result = 0;  // result to return

  // Combine register and binary read command
  byte dataToSend = thisRegister | READ; 

  // Select chip by setting pin low
  digitalWrite(chipSelectPin, LOW); 

  // Print to serial what due is sending
  Serial.print("Sending: "); Serial.println(dataToSend, BIN); 

  // Send the chip the register to read
  SPI.transfer(dataToSend); 

  // Send 0 to read response
  result = SPI.transfer(0x00); 
  

  // Deselect the chip
  digitalWrite(chipSelectPin, HIGH); 

  return (result); 
}

void writeRegister(byte thisRegister, byte thisValue){

  // Combine register with write byte 
  byte dataToSend = thisRegister | WRITE; 

  // Select chip
  digitalWrite(chipSelectPin, LOW); 

  // Send register
  SPI.transfer(dataToSend);

  // Send value to record in register
  SPI.transfer(thisValue); 

  // Deselect the chip
  digitalWrite(chipSelectPin, HIGH); 
}

No matter what address I send to read, I get 255 in binary (11111111). I have double checked my wiring and had a lab mate double check it as well. I have tried configuring the chip in both the setup and the loop. Not sure what the issue is. Any help would be greatly appreciated.

Thank you so much,
Trevor

IMO, since the sequence to read Product ID requires a read in slave memory, after sending a command to read Product_ID register , you should send a command to read the Status register until OTP_Read_DONE bit is set OR check INT pin prior reading Product_ID.

Thank you for your response. I've tried this, but I think the issue is still that the clock and the MOSI line are not matching up. Based on what the analog discovery is showing me, the chip is only receiving the bits starting from the third bit I send. Am I doing something wrong that would cause this to happen?

Bumping this. I have tried configuring the chip to use the interrupt pins, but the interrupt pin never changes. I can't get any response from the chip. I have used two different chips in case one of them was bad. Not sure what the issue is. Surely there is a way to do it. I would really appreciate anyone's help on this.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.