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
58 changes: 24 additions & 34 deletions src/SparkFun_MMC5983MA_Arduino_Library.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ bool SFE_MMC5983MA::areYZChannelsEnabled()
bool SFE_MMC5983MA::setFilterBandwidth(uint16_t bandwidth)
{
// These must be set/cleared using the shadow memory since it can be read
// using getFilterBandwith()
// using getFilterBandwidth()
bool success;

switch (bandwidth)
Expand Down Expand Up @@ -492,7 +492,7 @@ bool SFE_MMC5983MA::setFilterBandwidth(uint16_t bandwidth)
return success;
}

uint16_t SFE_MMC5983MA::getFilterBandwith()
uint16_t SFE_MMC5983MA::getFilterBandwidth()
{
bool bw0 = isShadowBitSet(INT_CTRL_1_REG, BW0);
bool bw1 = isShadowBitSet(INT_CTRL_1_REG, BW1);
Expand Down Expand Up @@ -522,6 +522,20 @@ uint16_t SFE_MMC5983MA::getFilterBandwith()
return retVal;
}

uint16_t SFE_MMC5983MA::getTimeout()
{
// It is rare but there are some devices and some circumstances where the code can become
// stuck in the getMeasurement loop waiting for the MEAS_M_DONE bit to go high.
// We have seen this on SPI where the MMC5983 is sharing the bus with (e.g.) an ISM330 IMU
// which uses a different SPI mode.
// A solution is to timeout after 4 * the measurement time (defined by BW1/0).
uint16_t timeOut = getFilterBandwidth(); // 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)
return timeOut;
}

bool SFE_MMC5983MA::enableContinuousMode()
{
// This bit must be set through the shadow memory or we won't be
Expand Down Expand Up @@ -925,14 +939,8 @@ uint32_t SFE_MMC5983MA::getMeasurementX()
return 0;
}

// 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)
// Wait until measurement is completed or times out
uint16_t timeOut = getTimeout();
do
{
// Wait a little so we won't flood MMC with requests
Expand Down Expand Up @@ -970,14 +978,8 @@ uint32_t SFE_MMC5983MA::getMeasurementY()
return 0;
}

// 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)
// Wait until measurement is completed or times out
uint16_t timeOut = getTimeout();
do
{
// Wait a little so we won't flood MMC with requests
Expand Down Expand Up @@ -1015,14 +1017,8 @@ uint32_t SFE_MMC5983MA::getMeasurementZ()
return 0;
}

// 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)
// Wait until measurement is completed or times out
uint16_t timeOut = getTimeout();
do
{
// Wait a little so we won't flood MMC with requests
Expand Down Expand Up @@ -1060,14 +1056,8 @@ bool SFE_MMC5983MA::getMeasurementXYZ(uint32_t *x, uint32_t *y, uint32_t *z)
return false;
}

// 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)
// Wait until measurement is completed or times out
uint16_t timeOut = getTimeout();
do
{
// Wait a little so we won't flood MMC with requests
Expand Down
8 changes: 6 additions & 2 deletions src/SparkFun_MMC5983MA_Arduino_Library.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ class SFE_MMC5983MA
// Checks if a specific bit is set on a register memory shadow
bool isShadowBitSet(uint8_t registerAddress, const uint8_t bitMask);

// Return a timeout for getMeasurement based on BW1/0
uint16_t getTimeout();

public:
// Default constructor.
SFE_MMC5983MA() = default;
Expand Down Expand Up @@ -139,8 +142,9 @@ class SFE_MMC5983MA
// Sets decimation filter bandwidth. Allowed values are 800, 400, 200 or 100. Defaults to 100 on invalid values.
bool setFilterBandwidth(uint16_t bandwidth);

// Gets current decimation filter bandwith. Values are in Hz.
uint16_t getFilterBandwith();
// Gets current decimation filter bandwidth. Values are in Hz.
uint16_t getFilterBandwidth(); // Typo fix - #17
uint16_t getFilterBandwith() { return getFilterBandwidth(); } // Retained for backward compatibility

// Enables continuous mode. Continuous mode frequency must be greater than 0.
bool enableContinuousMode();
Expand Down