Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 08:25 28 Nov 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : MM 1-wire CRC confusion

Author Message
Blackened

Regular Member

Joined: 11/08/2012
Location: Australia
Posts: 66
Posted: 12:42am 17 Aug 2013
Copy link to clipboard 
Print this post

Ok, this is probably obvious to those here who have a thorough knowledge of programming. But the following has taken me quite some time to figure out, and I'm still not sure I've got it right.

Appendix C of the MMBasic manual states:
  Quote  OWCRC8(len, cdata [, cdata…]) Processes the cdata and returns the 8 bit CRC

But that's the extent of the explanation.

However Gerard's own code sample found here contains:
1090 cmd(0) = &h55
1390 OWWRITE io_pin,1,10,cmd(0)
1400 OWREAD io_pin,2,9,rsp(0)
1410 crc = OWCRC8(9,rsp(0))
1420 ? "Device ";device;" - Data: (";rsp(0);",";rsp(1);",";rsp(2);",";rsp(3);",";rsp(4);",";rs p(5);",";rsp(6);",";rsp(7);",";rsp(8);" ), CRC: ";crc
1430 IF crc <> 0 THEN ' If data is corrupt


The code sample suggests that OWCRC8() returns a zero if the data isn't corrupt? Is this correct? And only returns the 8bit CRC if the data is corrupt?

My programming experience prior to my experimenting with MMBasic consisted of a course more than a decade ago, and I only ever output data to file,screen or printer so I'm really struggling to understand the way MMBasic implements the CRC. I've googled CRC, read the datasheet for the DS18B20, and studied the manual but I'm still not confident that I understand this correctly.

Friendly feedback:
I greatly appreciate Gerard's contribution to MMBasic, but the accompanying documentation doesn't quite "fit" with the idea that MMBasic is for beginners IMHO. This particular beginner requires a bit more hand holding I'm afraid! I humbly suggest an expanded Appendix C, with maybe some code examples and expanded explanations? I'm wondering what else the 1-wire functions do that aren't explicitly documented. Probably obvious to those of you familiar with serial comms etc... but I've never tried that either.
 
CircuitGizmos

Guru

Joined: 08/09/2011
Location: United States
Posts: 1425
Posted: 02:51am 17 Aug 2013
Copy link to clipboard 
Print this post

If you read through the example in Beginning Maximite does that help clear up anything?

Micromites and Maximites! - Beginning Maximite
 
Blackened

Regular Member

Joined: 11/08/2012
Location: Australia
Posts: 66
Posted: 03:58am 17 Aug 2013
Copy link to clipboard 
Print this post

  CircuitGizmos said   If you read through the example in Beginning Maximite does that help clear up anything?


It's a great reference. Very useful and visual too. I wish I'd seen this explanation when I was first trying to understand temperature reading etc... I've kept a copy on the laptop due to your expanded explanations for a while now thanks

Unfortunately it doesn't cover CRC any more than the standard Manual does
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 3804
Posted: 04:35am 17 Aug 2013
Copy link to clipboard 
Print this post

The common CRC is a constant (0 or -1 or whatever) if applied to correct data and anything else if the data is corrupted.

Looks like the len (9, above) data items starting at rsp(0) are supposed to result in a CRC of 0.

Maybe google or the device data sheet will show if that's right.

(As a circuit, a CRC involves fed back bits; mathematically a function with specifically chosen behaviour usually chosen to avoid known/expected types of data corruption in the situation where it's being used - and the initial value is also chosen to be resistant to corruption.)

John
 
Blackened

Regular Member

Joined: 11/08/2012
Location: Australia
Posts: 66
Posted: 05:04am 17 Aug 2013
Copy link to clipboard 
Print this post

Thanks JohnS,

I admit freely that I'm no CRC expert and my eyes tend to glaze over whenever I try to make sense of the specific method with which the 1-wire devices calculate the CRC value. An excerpt from the datasheet is at the bottom of this post.

My understanding of the above code (not necessarily correct) is as follows:

1400 OWREAD io_pin,2,9,rsp(0)
This piece of the above code reads 9 bytes from the scratchpad of a DS18B20 temperature probe. The first 2 bytes are really all that's required if you only want the temperature data, but the final byte is where the CRC value is held. 99% sure of this one.

1410 crc = OWCRC8(9,rsp(0))
This line is where I'm not sure exactly what's going on. It would seem that it takes all 9 bytes, re-calculates the CRC from the first 8 bytes, compares that with the 9th CRC byte of the received data and returns a value (?) depending on the comparison.

1430 IF crc <> 0 THEN ' If data is corrupt
This line seems to support the idea that a returned value of "0" means no error found? I don't really understand what you mean when you refer to "The common CRC"? I'll go google it shortly.

This quote is from the DS18B20 Datasheet:
  Quote  CRC GENERATION
CRC bytes are provided as part of the DS18B20’s 64-bit ROM code and in the 9th byte of the scratchpad memory. The ROM code CRC is calculated from the first 56 bits of the ROM code and is contained in the most significant byte of the ROM. The scratchpad CRC is calculated from the data stored in the scratchpad, and therefore it changes when the data in the scratchpad changes. The CRCs provide the bus master with a method of data validation when data is read from the DS18B20. To verify that data has been read correctly, the bus master must re-calculate the CRC from the received data and then compare this value to either the ROM code CRC (for ROM reads) or to the scratchpad CRC (for scratchpad reads). If the calculated CRC matches the read CRC, the data has been received error free. The comparison of CRC values and the decision to continue with an operation are determined entirely by the bus master. There is no circuitry inside the DS18B20 that prevents a command sequence from proceeding if the DS18B20 CRC (ROM or scratchpad) does not match the value generated by the bus master.
The equivalent polynomial function of the CRC (ROM or scratchpad) is:
CRC = X8 + X5 + X4 + 1
The bus master can re-calculate the CRC and compare it to the CRC values from the DS18B20 using the polynomial generator shown in Figure 9. This circuit consists of a shift register and XOR gates, and the shift register bits are initialized to 0. Starting with the least significant bit of the ROM code or the least significant bit of byte 0 in the scratchpad, one bit at a time should shifted into the shift register. After shifting in the 56th bit from the ROM or the most significant bit of byte 7 from the scratchpad, the polynomial generator will contain the re-calculated CRC. Next, the 8-bit ROM code or scratchpad CRC from the DS18B20 must be shifted into the circuit. At this point, if the re-calculated CRC was correct, the shift register will contain all 0s. Additional information about the Maxim 1-Wire cyclic redundancy check
DS18B20
9 of 22
is available in Application Note 27: Understanding and Using Cyclic Redundancy Checks with Maxim iButton Products.
 
BobD

Guru

Joined: 07/12/2011
Location: Australia
Posts: 935
Posted: 10:24am 17 Aug 2013
Copy link to clipboard 
Print this post

My thoughts:

The MMBasic OW function of OWCRC8 is optional but if not used and there is a failure it will not be noticed except by (possibly) a data value that is obviously wrong or it causes the MMBasic program to crash. The use of the CRC allows for communications environments that may be temporarily not ideal. If the data is wrong then it can be ignored and requested again. Usage of this function should provide your program with confidence that the data has not been corrupted by the communication. It is not a guarantee that the DS18B20 has not corrupted the data before it calculated the CRC (a bum sensor etc.).

The DS18B20 sends a block of data and the last byte is the CRC. The OWCRC8 function processes the received data (including the CRC byte) using the stated algorithm (from the device datasheet) and when all of the data and the CRC byte has been processed the value should be zero. If not then there has been an error somewhere and the data should be discarded. The non zero value (if any) is not the value of the CRC byte. It is just the result of the CRC calculation.

  Quote   The code sample suggests that OWCRC8() returns a zero if the data isn't corrupt? Is this correct? And only returns the 8bit CRC if the data is corrupt?

Not quite correct. You never know what the actual CRC byte is, just the result of the CRC process expressed as zero or non zero.

  Quote   I'm really struggling to understand the way MMBasic implements the CRC.

Why do you need to know how this function is implemented? Do you wonder how other MMBasic functions are implemented? Just use it as with the example. Is it the example you have problems with?

If I have misjudged your questions please sort me out and ask again.

About CRC: If you want an explanation about CRC generation and checking then Wikipedia has a description here. It is enough to fry your brain.

Here is a very simple example of a CRC (not the OW one). It uses an Exclusive Or (aka XOR) accumulation of all of the bytes. Suppose your data stream is an 8 byte string ABCDEFGH then the CRC byte is hexadecimal 08. The actual data (in hex) is 414243444546474808. The receiver gets the 8 bytes and its CRC calculation is hex 08. It receives the CRC byte (hex 08) and its calculated value is then zero.

If we had a comms accident and we picked up a bit in the first character and it became a Q (hex 51) instead of an A (hex 41) but the sender still sent an A. The CRC byte becomes hex 18 as calculated by the receiver but the sender still sends a hex 08. The XOR result after the CRC bytes are compared, is then hex 10. It is not the actual CRC byte but it is non zero which indicates that what is received is different from what is sent.

I calculated these XORs using the Windoze 8 calculator in hexadecimal mode. Very useful.
 
Blackened

Regular Member

Joined: 11/08/2012
Location: Australia
Posts: 66
Posted: 12:50pm 17 Aug 2013
Copy link to clipboard 
Print this post

Thanks BobD

  BobD said  
  Quote   The code sample suggests that OWCRC8() returns a zero if the data isn't corrupt? Is this correct? And only returns the 8bit CRC if the data is corrupt?

Not quite correct. You never know what the actual CRC byte is, just the result of the CRC process expressed as zero or non zero.


That's the piece of the puzzle I'd been struggling the most to comprehend right there. I got the impression from the way the manual is worded, that the crc value was being returned by the OWCRC8() function, not the result of comparing the two values. And with that in mind, nothing else fit! *Dalek saying "MALFUNCTION! MALFUNCTION!*

I now have a better understanding of the way a CRC check is performed too, which helped to clarify what was going on. And you've just reinforced what I thought I knew thanks. Most explanations I found online involved a lot of binary maths which I am only just beginning to understand. It's been a big learning curve for me. Every time I tried to research this, I found myself faced with yet another thing to teach myself. It's actually been very informative and not at all a waste of time . I just lament the fact it's taken me so long to get it into my thick skull, like most things, once you know it seems fairly straight forward.
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024