I am using a Nodemcu-32S to communicate with an I2C device (touchpads). I noticed while uploading the configuration, the CRC (checksum) always comes back incorrect. After doing a little digging with a logic analyzer, I realized that it never transmits the final byte from my configuration array, which is the checksum value. The function I use for writing to the I2C bus is as follows:
bool writeI2C(uint16_t address, uint8_t command, uint8_t *data, uint8_t dataLen)
{
byte err;
uint8_t dataPos = 0;
Wire.beginTransmission(address);
Wire.write(command);
for (dataPos; dataPos < dataLen; dataPos++)
{
Wire.write(data[dataPos]);
}
delay(70);
err = Wire.endTransmission();
if (err > 0)
{
Serial.printf("writeI2C Error Code: 0x0%d\n", err);
return false;
}
else
return true;
}
With the following function call:
uint8_t config[128] = {0}; <- (the array is filled with values before the function call)
if (!writeI2C(SLAVE_ADDR, command, config, 128))
{
Serial.println("Failed to update config.");
continue; // try again
}
According to the logic in my function, it should transmit the address, then the register (command
in this case) followed by 128 bytes of data (130 bytes total). With my logic analyzer, however, I get only 129 'chunks' of data. So I figured I'd add dummy writes if dataLen
met a condition:
bool writeI2C(uint16_t address, uint8_t command, uint8_t *data, uint8_t dataLen)
{
byte err;
uint8_t dataPos = 0;
Wire.beginTransmission(address);
Wire.write(command);
for (dataPos; dataPos < dataLen; dataPos++)
{
Wire.write(data[dataPos]);
}
if (dataLen > 100)
{
Wire.write(0x00);
Wire.write(0x00);
Wire.write(0x00);
Wire.write(0x00);
Wire.write(0x00);
}
err = Wire.endTransmission();
delay(70);
if (err > 0)
{
Serial.printf("writeI2C Error Code: 0x0%d\n", err);
return false;
}
else
return true;
}
None of the dummy writes are outputting and the behavior is the same. The final two bytes should be: config[126] = 0x45
and config[127] = 0xC9
, but my logic analyzer is shows that the transmission stops at 0x45 + ACK
.