Zanduino / MCP7940

Arduino Library to access the MCP7940M, MCP7940N and MCP7940x Real-Time chips
GNU General Public License v3.0
35 stars 22 forks source link

Question about int8_t MCP7940_Class::calibrate(const int8_t newTrim)... #62

Closed davidlehrian closed 2 years ago

davidlehrian commented 2 years ago

I was looking though the code and saw something that looked odd to me. Lines 469 - 473 seem to be doing nothing. Here are the lines.

  int8_t trim = abs(newTrim);  // Make a local copy of absolute value
  if (newTrim < 0)             // if the trim is less than 0
  {
    trim = 0x80 | trim;                                // set non-excess 128 negative val
  }                                                    // of if-then value of trim is less than 0

A new variable trim is set equal to the absolute value of the passed in newTrim which makes bit 8 of trim 0. Then, if newTrim is negative trim is or'ed with 0x80 which flips bit 8 back to 1. I fail to see the point of this code. It seems to be setting bit 8 to 0 and then if it was originally 1 it sets it back to 1. Why not just use the passed in trim value directly?

SV-Zanshin commented 2 years ago

This is Excess-128 math. A value of b11111111 is -1, but needs to be represented as b10000001. So getting the abs() converts it to a "normal" positive integer, then the MSB is set to 1 to denote a negative number.

davidlehrian commented 2 years ago

Oh interesting. I learned something. Thanks.

SV-Zanshin commented 2 years ago

That Excess 128 takes a bit of getting used to at first, and in this case the MCP7940 doesn't use it, so it needs to get converted.

davidlehrian commented 2 years ago

Yeah, I read through the datasheet and I see what it is expecting for trim in the register so it makes sense even though it seems a little backwards where the 1 in bit means to add the trim value every cycle and 0 means to subtract it. But then I read through the trim calculation and that calculates how many cycles it is off. A trim value of -100 is 200 ticks behind so you need to add it to the tick count which is exactly what the register is doing. Kind of convoluted but it works.