MS5611 CRC check
Hi, Many thanks for making your work available for others to look at.
I am trying out MPU9250/MPU9250_MS5611_BasicAHRS_t3.ino on a Arduino Nano modified for 3.3V with a CJMCU-117 ebay board.
The CRC check for the MS5611 doesn't work and the method you use in the repository doesn't match the AN520 C-code example for MS56xx, MS57xx, and MS58xx series pressure sensors. Ref. http://www.amsys-sensor.eu/sheets/amsys.fr.an520_e.pdf
You have a number of issues why the CRC check is not working:
- MS5611PromRead was only reading 7 values, the 8th contains the CRC code in the last 4 bits.
void MS5611PromRead(uint16_t * destination) { uint8_t data[2] = {0, 0}; for (uint8_t ii = 0; ii <= 7; ii++) { //gw change to read all 8 values Wire.beginTransmission(MS5611_ADDRESS); // Initialize the Tx buffer Wire.write(0xA0 | ii << 1); // Put PROM address in Tx buffer //Wire.endTransmission(I2C_NOSTOP); // Send the Tx buffer, but send a restart to keep connection alive Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive uint8_t i = 0; Wire.requestFrom(MS5611_ADDRESS, 2); // Read two bytes from slave PROM address while (Wire.available()) { data[i++] = Wire.read(); } // Put read results in the Rx buffer destination[ii] = (uint16_t) (((uint16_t) data[0] << 8) | data[1]); // construct PROM data for return to main program } }
-
The refCRC should be calculated this way. unsigned char refCRC = Pcal[7] & 0x000F ; // last 4 bits of C7 GW
-
MS5611checkCRC was modified per the AN520 doc above.
unsigned char MS5611checkCRC(uint16_t * n_prom) // calculate checksum from PROM register contents { int cnt; // simple counter unsigned int n_rem; // crc reminder unsigned int crc_read; // original value of the crc unsigned char n_bit; n_rem = 0x00; crc_read = n_prom[7]; //save read CRC n_prom[7] = (0xFF00 & (n_prom[7])); //CRC byte is replaced by 0 for (cnt = 0; cnt < 16; cnt++) // operation is performed on bytes { // choose LSB or MSB if (cnt % 2 == 1) n_rem ^= (unsigned short) ((n_prom[cnt >> 1]) & 0x00FF); else n_rem ^= (unsigned short) (n_prom[cnt >> 1] >> 8); for (n_bit = 8; n_bit > 0; n_bit--) { if (n_rem & (0x8000)) { n_rem = (n_rem << 1) ^ 0x3000; } else { n_rem = (n_rem << 1); } } } n_rem = (0x000F & (n_rem >> 12)); // final 4-bit reminder is CRC code n_prom[7] = crc_read; // restore the crc_read to its original place return (n_rem ^ 0x0); }
The Calculated CRC now matches the prom CRC value. Hope that helps, Gord
I haven't had any trouble reading and matching the CRC. Maybe an AVR vs. Cortex issue?
On Sun, Aug 13, 2017 at 11:49 AM, Gord1 [email protected] wrote:
Hi, Many thanks for making your work available for others to look at.
I am trying out MPU9250/MPU9250_MS5611_BasicAHRS_t3.ino on a Arduino Nano modified for 3.3V with a CJMCU-117 ebay board.
The CRC check for the MS5611 doesn't work and the method you use in the repository doesn't match the AN520 C-code example for MS56xx, MS57xx, and MS58xx series pressure sensors. Ref. http://www.amsys-sensor.eu/ sheets/amsys.fr.an520_e.pdf
You have a number of issues why the CRC check is not working:
- MS5611PromRead was only reading 7 values, the 8th contains the CRC code in the last 4 bits.
void MS5611PromRead(uint16_t * destination) { uint8_t data[2] = {0, 0}; for (uint8_t ii = 0; ii <= 7; ii++) { //gw change to read all 8 values Wire.beginTransmission(MS5611_ADDRESS); // Initialize the Tx buffer Wire.write(0xA0 | ii << 1); // Put PROM address in Tx buffer //Wire.endTransmission(I2C_NOSTOP); // Send the Tx buffer, but send a restart to keep connection alive Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive uint8_t i = 0; Wire.requestFrom(MS5611_ADDRESS, 2); // Read two bytes from slave PROM address while (Wire.available()) { data[i++] = Wire.read(); } // Put read results in the Rx buffer destination[ii] = (uint16_t) (((uint16_t) data[0] << 8) | data[1]); // construct PROM data for return to main program } }
The refCRC should be calculated this way. unsigned char refCRC = Pcal[7] & 0x000F ; // last 4 bits of C7 GW 2.
MS5611checkCRC was modified per the AN520 doc above.
unsigned char MS5611checkCRC(uint16_t * n_prom) // calculate checksum from PROM register contents { int cnt; // simple counter unsigned int n_rem; // crc reminder unsigned int crc_read; // original value of the crc unsigned char n_bit; n_rem = 0x00; crc_read = n_prom[7]; //save read CRC n_prom[7] = (0xFF00 & (n_prom[7])); //CRC byte is replaced by 0 for (cnt = 0; cnt < 16; cnt++) // operation is performed on bytes { // choose LSB or MSB if (cnt % 2 == 1) n_rem ^= (unsigned short) ((n_prom[cnt >> 1]) & 0x00FF); else n_rem ^= (unsigned short) (n_prom[cnt >> 1] >> 8); for (n_bit = 8; n_bit > 0; n_bit--) { if (n_rem & (0x8000)) { n_rem = (n_rem << 1) ^ 0x3000; } else { n_rem = (n_rem << 1); } } } n_rem = (0x000F & (n_rem >> 12)); // final 4-bit reminder is CRC code n_prom[7] = crc_read; // restore the crc_read to its original place return (n_rem ^ 0x0); }
The Calculated CRC now matches the prom CRC value. Hope that helps, Gord
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/174, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qjTBK8cSCSTF-b8KmaAenp9hpu_lks5sX0U4gaJpZM4O1w9b .
Hmm, how could that be? I've never used Cortex.
You get your refCRC like this: unsigned char refCRC = Pcal[0] >> 12;
While I get mine like unsigned char refCRC = Pcal[7] & 0x000F ; // last 4 bits of C7 GW
Ref MS5611 doc http://www.te.com/commerce/DocumentDelivery/DDEController?Action=srchrtrv&DocNm=MS5611-01BA03&DocType=Data+Sheet&DocLang=English
See Figure 16: Memory PROM mapping
The only way that they could be the same is if the order was completely reversed your Pcal[0] is equal to my Pcal[7] but the order of the bits were reversed. MS5611 Data comes out MSB first for each Pcal read per Figure 15 and you handle that correctly with destination[ii] = (uint16_t) (((uint16_t) data[0] << 8) | data[1]); // construct PROM data for return to main program
Could it be that you just got a (un)lucky check? Gordon
I doubt it, I have assembled and tested dozens of MS5611-containing breakouts. Not sure why you are seeing something different.
IIRC the CRC is stored in more than one location, maybe that is the answer.
On Sun, Aug 13, 2017 at 2:27 PM, Gord1 [email protected] wrote:
Hmm, how could that be? I've never used Cortex.
You get your refCRC like this: unsigned char refCRC = Pcal[0] >> 12;
While I get mine like unsigned char refCRC = Pcal[7] & 0x000F ; // last 4 bits of C7 GW
Ref MS5611 doc http://www.te.com/commerce/DocumentDelivery/DDEController?Action=srchrtrv& DocNm=MS5611-01BA03&DocType=Data+Sheet&DocLang=English
See Figure 16: Memory PROM mapping
The only way that they could be the same is if the order was completely reversed your Pcal[0] is equal to my Pcal[7] but the order of the bits were reversed. MS5611 Data comes out MSB first for each Pcal read per Figure 15 and you handle that correctly with destination[ii] = (uint16_t) (((uint16_t) data[0] << 8) | data[1]); // construct PROM data for return to main program
Could it be that you just got a (un)lucky check? Gordon
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/174#issuecomment-322068604, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qkH-C7w5J6AhzqbEToolYTGXzhKeks5sX2o7gaJpZM4O1w9b .
Thanks for your replies. We are getting different answers because we are calculating it differently. Mine is based on the AN520 document above along with the datasheet above.
What is the source of your CRC check code? Which MS5611 datasheet are you using?
Gordon
I got mine from Measurement Specialties. Probably the same document, or they sent me the code, can't remember.
On Sun, Aug 13, 2017 at 2:51 PM, Gord1 [email protected] wrote:
Thanks for your replies. We are getting different answers because we are calculating it differently. Mine is based on the AN520 document above along with the datasheet above.
What is the source of your CRC check code? Which MS5611 datasheet are you using?
Gordon
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/174#issuecomment-322069788, or mute the thread https://github.com/notifications/unsubscribe-auth/AGY1qnfzRhV2cDXqQZgg9q63dsGVjlnrks5sX2_QgaJpZM4O1w9b .
Not the same document as the code doesn't match. Mine is copied verbatim from the AN520 doc (Aug. 09, 2011) and it works while yours doesn't, so go figure. You say you don't have a problem and I'll leave it at that. Gordon
@kriswiner I think @Gord1 is right, you are not seeing issue because you are not comparing and even not printing nCRC and refCRC. The right CRC check is this one:
unsigned char crc4(uint16_t n_prom[])
{
int cnt;
unsigned int n_rem;
unsigned int crc_read;
unsigned char n_bit;
n_rem = 0x00;
crc_read = n_prom[7]; /* Save the original CRC */
n_prom[7] = (0xff00 & (n_prom[7])); /* Lower byte of CRC is zeroed */
for (cnt = 0; cnt < 16; cnt++) /* Perform the CRC for 16 bytes */
{
/* Choose LSB or MSB */
if (cnt % 2 == 1)
{
n_rem ^= (unsigned short) ((n_prom[cnt >> 1]) & 0x00ff);
}
else
{
n_rem ^= (unsigned short) (n_prom[cnt >> 1] >> 8);
}
for (n_bit = 8; n_bit > 0; n_bit--)
{
if (n_rem & (0x8000))
{
n_rem = (n_rem << 1) ^ 0x3000;
}
else
{
n_rem = (n_rem << 1);
}
}
}
n_rem = (0x000f & (n_rem >> 12)); /* The final 4-bit reminder is CRC code */
n_prom[7] = crc_read; /* Restore the crc_read to its place */
return (n_rem ^ 0x00); /* Why? It is on AN520 CRC-4 PDF */
}
OK, appreciate the input. I haven't used one of these in five years so no hurry to correct this problem...
On Tue, Jan 18, 2022 at 4:04 PM Alan Carvalho de Assis < @.***> wrote:
@kriswiner https://github.com/kriswiner I think @Gord1 https://github.com/Gord1 is right, you are not seeing issue because you are not comparing and even not printing nCRC and refCRC. The right CRC check is this one:
unsigned char crc4(uint16_t n_prom[]) { int cnt; unsigned int n_rem; unsigned int crc_read; unsigned char n_bit;
n_rem = 0x00; crc_read = n_prom[7]; /* Save the original CRC / n_prom[7] = (0xff00 & (n_prom[7])); / Lower byte of CRC is zeroed */
for (cnt = 0; cnt < 16; cnt++) /* Perform the CRC for 16 bytes / { / Choose LSB or MSB */
if (cnt % 2 == 1) { n_rem ^= (unsigned short) ((n_prom[cnt >> 1]) & 0x00ff); } else { n_rem ^= (unsigned short) (n_prom[cnt >> 1] >> 8); } for (n_bit = 8; n_bit > 0; n_bit--) { if (n_rem & (0x8000)) { n_rem = (n_rem << 1) ^ 0x3000; } else { n_rem = (n_rem << 1); } }}
n_rem = (0x000f & (n_rem >> 12)); /* The final 4-bit reminder is CRC code / n_prom[7] = crc_read; / Restore the crc_read to its place / return (n_rem ^ 0x00); / Why? It is on AN520 CRC-4 PDF */ }
— Reply to this email directly, view it on GitHub https://github.com/kriswiner/MPU9250/issues/174#issuecomment-1015944491, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTDLKT7ETL6CBSPC4WXECTUWX5YVANCNFSM4DWXB5NQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.
You are receiving this because you were mentioned.Message ID: @.***>