Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=SparkFun MMC5983MA Magnetometer Arduino Library
version=1.1.2
version=1.1.3
author=SparkFun Electronics
maintainer=SparkFun Electronics
sentence=A I2C/SPI library for the MMC5983MA magnetic compass sensor.
Expand Down
66 changes: 54 additions & 12 deletions src/SparkFun_MMC5983MA_Arduino_Library.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,16 +249,21 @@ int SFE_MMC5983MA::getTemperature()
return -99;
}

// Wait until measurement is completed
// Wait until measurement is completed.
// It is rare but there are some devices and some circumstances where the code can become
// stuck in this loop waiting for MEAS_T_DONE to go high. The solution is to timeout after 5ms.
uint8_t timeOut = 5;
do
{
// Wait a little so we won't flood MMC with requests
delay(1);
} while (!mmc_io.isBitSet(STATUS_REG, MEAS_T_DONE));
timeOut--;
} while ((!mmc_io.isBitSet(STATUS_REG, MEAS_T_DONE)) && (timeOut > 0));

clearShadowBit(INT_CTRL_0_REG, TM_T, false); // Clear the bit - in shadow memory only

// Get raw temperature value from the IC.
// Get raw temperature value from the IC
// even if a timeout occurred - old data vs no data
uint8_t result = 0;
if (!mmc_io.readSingleByte(T_OUT_REG, &result))
{
Expand Down Expand Up @@ -920,19 +925,28 @@ uint32_t SFE_MMC5983MA::getMeasurementX()
return 0;
}

// Wait until measurement is completed
// Wait until measurement is completed.
// It is rare but there are some devices and some circumstances where the code can become
// stuck in this loop waiting for MEAS_M_DONE to go high. The solution is to timeout after
// 4 * the measurement time (defined by BW1/0).
uint16_t timeOut = getFilterBandwith(); // Read the bandwidth (100/200/400/800Hz) from shadow
timeOut = 800 / timeOut; // Convert timeOut to 8/4/2/1ms
timeOut *= 4; // Convert bw to 32/16/8/4ms
timeOut += 1; // Add 1 just in case (for 800Hz)
do
{
// Wait a little so we won't flood MMC with requests
delay(1);
} while (!mmc_io.isBitSet(STATUS_REG, MEAS_M_DONE));
timeOut--;
} while ((!mmc_io.isBitSet(STATUS_REG, MEAS_M_DONE)) && (timeOut > 0));

clearShadowBit(INT_CTRL_0_REG, TM_M, false); // Clear the bit - in shadow memory only

uint32_t result = 0;
uint8_t buffer[2] = {0};
uint8_t buffer2bit = 0;

// Read the field even if a timeout occurred - old data vs no data
mmc_io.readMultipleBytes(X_OUT_0_REG, buffer, 2);
mmc_io.readSingleByte(XYZ_OUT_2_REG, &buffer2bit);

Expand All @@ -956,19 +970,28 @@ uint32_t SFE_MMC5983MA::getMeasurementY()
return 0;
}

// Wait until measurement is completed
// Wait until measurement is completed.
// It is rare but there are some devices and some circumstances where the code can become
// stuck in this loop waiting for MEAS_M_DONE to go high. The solution is to timeout after
// 4 * the measurement time (defined by BW1/0).
uint16_t timeOut = getFilterBandwith(); // Read the bandwidth (100/200/400/800Hz) from shadow
timeOut = 800 / timeOut; // Convert timeOut to 8/4/2/1ms
timeOut *= 4; // Convert bw to 32/16/8/4ms
timeOut += 1; // Add 1 just in case (for 800Hz)
do
{
// Wait a little so we won't flood MMC with requests
delay(1);
} while (!mmc_io.isBitSet(STATUS_REG, MEAS_M_DONE));
timeOut--;
} while ((!mmc_io.isBitSet(STATUS_REG, MEAS_M_DONE)) && (timeOut > 0));

clearShadowBit(INT_CTRL_0_REG, TM_M, false); // Clear the bit - in shadow memory only

uint32_t result = 0;
uint8_t buffer[2] = {0};
uint8_t buffer2bit = 0;

// Read the field even if a timeout occurred - old data vs no data
mmc_io.readMultipleBytes(Y_OUT_0_REG, buffer, 2);
mmc_io.readSingleByte(XYZ_OUT_2_REG, &buffer2bit);

Expand All @@ -992,18 +1015,27 @@ uint32_t SFE_MMC5983MA::getMeasurementZ()
return 0;
}

// Wait until measurement is completed
// Wait until measurement is completed.
// It is rare but there are some devices and some circumstances where the code can become
// stuck in this loop waiting for MEAS_M_DONE to go high. The solution is to timeout after
// 4 * the measurement time (defined by BW1/0).
uint16_t timeOut = getFilterBandwith(); // Read the bandwidth (100/200/400/800Hz) from shadow
timeOut = 800 / timeOut; // Convert timeOut to 8/4/2/1ms
timeOut *= 4; // Convert bw to 32/16/8/4ms
timeOut += 1; // Add 1 just in case (for 800Hz)
do
{
// Wait a little so we won't flood MMC with requests
delay(1);
} while (!mmc_io.isBitSet(STATUS_REG, MEAS_M_DONE));
timeOut--;
} while ((!mmc_io.isBitSet(STATUS_REG, MEAS_M_DONE)) && (timeOut > 0));

clearShadowBit(INT_CTRL_0_REG, TM_M, false); // Clear the bit - in shadow memory only

uint32_t result = 0;
uint8_t buffer[3] = {0};

// Read the field even if a timeout occurred - old data vs no data
mmc_io.readMultipleBytes(Z_OUT_0_REG, buffer, 3);

result = buffer[0]; // out[17:10]
Expand All @@ -1028,16 +1060,26 @@ bool SFE_MMC5983MA::getMeasurementXYZ(uint32_t *x, uint32_t *y, uint32_t *z)
return false;
}

// Wait until measurement is completed
// Wait until measurement is completed.
// It is rare but there are some devices and some circumstances where the code can become
// stuck in this loop waiting for MEAS_M_DONE to go high. The solution is to timeout after
// 4 * the measurement time (defined by BW1/0).
uint16_t timeOut = getFilterBandwith(); // Read the bandwidth (100/200/400/800Hz) from shadow
timeOut = 800 / timeOut; // Convert timeOut to 8/4/2/1ms
timeOut *= 4; // Convert bw to 32/16/8/4ms
timeOut += 1; // Add 1 just in case (for 800Hz)
do
{
// Wait a little so we won't flood MMC with requests
delay(1);
} while (!mmc_io.isBitSet(STATUS_REG, MEAS_M_DONE));
timeOut--;
} while ((!mmc_io.isBitSet(STATUS_REG, MEAS_M_DONE)) && (timeOut > 0));

clearShadowBit(INT_CTRL_0_REG, TM_M, false); // Clear the bit - in shadow memory only

return (readFieldsXYZ(x, y, z));
// Read the fields even if a timeout occurred - old data vs no data
// Return false if a timeout or a read error occurred
return ((readFieldsXYZ(x, y, z)) && (timeOut > 0));
}

bool SFE_MMC5983MA::readFieldsXYZ(uint32_t *x, uint32_t *y, uint32_t *z)
Expand Down