stevemarple / SoftWire

Software I2C implementation for Arduino and other Wiring-type environments
GNU Lesser General Public License v2.1
136 stars 31 forks source link

Restart condition is not issued #22

Closed hideakitai closed 2 years ago

hideakitai commented 3 years ago

Hi, thank you for the great work. I was trying to read the data with a restart condition like this.

uint8_t readByte(uint8_t address, uint8_t subAddress, SoftWire& wire) {
    wire.beginTransmission(address);
    wire.write(subAddress);
    wire.endTransmission(false);

    wire.requestFrom(address, (size_t)1);
    uint8_t data = 0;
    if (wire.available()) data = wire.read();

    return data;
}

A correct transaction with the Wire library looks like this.

Screen Shot 2021-06-22 at 20 13 32

But it seems that a restart condition is not issued with SoftWire. The hardware setup and code are exactly the same except for the use of SoftWire instead of Wire.

Screen Shot 2021-06-22 at 20 15 19

I've forced to use repeatedStart instead of start in Line 449 of SoftWire.h. Then I could issue a restart condition but the data was not correct.

Screen Shot 2021-06-23 at 19 43 33

Do you have any idea to work around this issue?

stevemarple commented 3 years ago

That looks like a bug as the repeated start condition is not sent. I need to find some time to look into this in more detail and remind myself of what is supposed to happen.

Can you please post a code snippet showing how you call the SoftWire constructor and setup the RX and TX buffers?

Nice logic traces - what did you use to capture them?

hideakitai commented 3 years ago

Thank you for the reply. I'm using the following setups.

// in the global scope
SoftWire sw(SDA, SCL);
char swTxBuffer[64];
char swRxBuffer[64];

// in the setup()
sw.setTxBuffer(swTxBuffer, sizeof(swTxBuffer));
sw.setRxBuffer(swRxBuffer, sizeof(swRxBuffer));
sw.setDelay_us(5);
sw.begin();

The entire code is here, and you can reproduce the problem by activating this line instead of the next one.

I'm using Logic Pro 16. It's a super easy and useful one :)

stevemarple commented 2 years ago

I finally found the time to investigate this properly. I believe it is fixed in v2.0.8. I wasn't able to test with the same I2C device as you, so I used a Microchip MCP79410 real-time clock. This is the logic analyzer trace obtained by writing to and then reading from that device. I2C traces

waynepiekarski commented 2 years ago

I was encountering a similar problem with 2.0.7 getting the WHO_AM_I register from an NXP FXOS8700 sensor, and after applying this patch my problem has been fixed. Thanks for fixing this.

stevemarple commented 2 years ago

I was encountering a similar problem with 2.0.7 getting the WHO_AM_I register from an NXP FXOS8700 sensor, and after applying this patch my problem has been fixed. Thanks for fixing this.

Thanks for reporting - I'll close this issue now I have confirmation it is fixed.