Adafruit_Seesaw
Adafruit_Seesaw copied to clipboard
NeoPixel::clear() writes more than 32 Bytes to I2C
-
List the steps to reproduce the problem below (if possible attach a sketch or copy the sketch code in too):
-
Call
seesaw_NeoPixel.clear()
withDEBUG_SERIAL
enabled -
Neopixel is not updated and the following error is printed:
I2CDevice could not write such a large buffer
-
-
Root cause:
- The reason seems to be, that
Neopixel::clear()
callsAdafruit_seesaw::write(SEESAW_NEOPIXEL_BASE, SEESAW_NEOPIXEL_BUF, writeBuf, 32)
with a size of 32 bytes, whileseesaw::write()
then prepends a prefix of sizeprefix_len=2
bytes for a total of 34 bytes.
- The reason seems to be, that
-
Fix:
- write at most 30 bytes in
Adafruit_seesaw::write()
fromNeopixel::clear()
. (Interestingly the offset is correctly calculated to make space for 4 Bytes of prefix + offsets).
- write at most 30 bytes in
Caller:
void seesaw_NeoPixel::clear() {
// Clear local pixel buffer
memset(pixels, 0, numBytes);
// Now clear the pixels on the seesaw
uint8_t writeBuf[32];
memset(writeBuf, 0, 32);
for(uint8_t offset = 0; offset < numBytes; offset += 32-4) {
writeBuf[0] = (offset >> 8);
writeBuf[1] = offset;
this->write(SEESAW_NEOPIXEL_BASE, SEESAW_NEOPIXEL_BUF, writeBuf, 32);
}
}
Callee:
bool Adafruit_seesaw::write(uint8_t regHigh, uint8_t regLow,
uint8_t *buf = NULL, uint8_t num = 0) {
uint8_t prefix[2];
prefix[0] = (uint8_t)regHigh;
prefix[1] = (uint8_t)regLow;
if (_flow != -1)
while (!::digitalRead(_flow))
yield();
if (!_i2c_dev->write(buf, num, true, prefix, 2)) {
return false;
}
return true;
}