I'm quite new to bug reporting on a forum. I'm sorry if this article seems not friendly for you.
******** Phenomenon ************
Wire.requestFrom(slav_addr, read_len) doesn't output NACK until {read_len+1}bytes of read is over.
******** How I found this bug **************
I'm using Arduino 0016 and found this bug when I tried to use an EEPROM(24C1024) from Arduino(pro mini 328) via I2C communication with Wire Library.
The EEPROM I use is designed to read sequentially: reading without specifying an address means reading from the next byte of the last read.
First I tested read and write operation like follows:
- write each byte data 0 to 255 into address 0 to 255
- read one byte using {Wire.requestFrom(ARRD, 1)} and send result w/ serial com using {while(Wire.available()){println((int)Wire.receive());}}.
- Repeat "2." 256 times.
This test supposed to output:
0
1
2
3
...
255
on the serial monitor. But the result I've got was:
0
2
4
....
This seems a bug described as follows:
- Wire.requestFrom(ADDR, 1) reads two bytes (=extra one byte) from EEPROM
- but Wire.available() returns 1 (though this supposed to be the # of buffered bytes)
Debugging using oscilloscope revealed that:
- NACK which supposed to come right after read a byte comes after two bytes of read in reality
Then I looked into sources of Wire library.
Wire.requestFrom() calls another library function twi_readFrom() in Wire/utility/twi.c and this funciton just sets registers to start master reader.
So the problem must be in the Interrupt handler: SIGNAL(TWI_vect) in Wire/utility/twi.c.
*********** How to fix this bug *************
As a result, I could fix this bug by editing three points in Wire/utility/twi.c.
$ diff twi.c.orig twi.c
126a127,129
if(length < 1){
return 0;
}
152c155
< if (twi_masterBufferIndex < length)
//if (twi_masterBufferIndex < length)
374c377
< if(twi_masterBufferIndex < twi_masterBufferLength){
if(twi_masterBufferIndex < (twi_masterBufferLength - 1)){