Richard-Gemmell / teensy4_i2c

An I2C library for the Teensy 4. Provides slave and master mode.
MIT License
92 stars 19 forks source link

raw/raw_find_slaves example not working? #18

Closed niek-dewit closed 3 years ago

niek-dewit commented 3 years ago

Hey there, me again! ;) trying to make some progress with my project. I want to replace the default wire library with this one. First thing I want to do is to simply write/read data to/from an EEPROM (FT24C512A). I started off by trying out the raw_find_slaves slaves example code. But it doesnt seem to work. I am getting the following errors:

Checking address 121
Master: FIFOs not empty in start(). TX: 1 RX: 0
Master: abort_transaction
  sending STOP
Master: ERROR timed out waiting for transfer to finish.
Unexpected error at address 121

Checking address 122
Master: Cannot start. Transaction still in progress. State: 0. Error code: 8
Master: abort_transaction
  sending STOP
Unexpected error at address 122

Checking address 123
Master: FIFOs not empty in start(). TX: 1 RX: 0
Master: abort_transaction
  sending STOP
Master: ERROR timed out waiting for transfer to finish.
Unexpected error at address 123

Checking address 124
Master: Cannot start. Transaction still in progress. State: 0. Error code: 8
Master: abort_transaction
  sending STOP
Unexpected error at address 124

Checking address 125
Master: FIFOs not empty in start(). TX: 1 RX: 0
Master: abort_transaction
  sending STOP
Master: ERROR timed out waiting for transfer to finish.
Unexpected error at address 125

Checking address 126
Master: Cannot start. Transaction still in progress. State: 0. Error code: 8
Master: abort_transaction
  sending STOP
Unexpected error at address 126

No I2C slave devices found.

When I power cycle, at the beginning it will print some other messages:


Checking address 77
ISR: enter: Master: abort_transaction
  sending STOP
ISR: enter: ISR: enter: Address not in use.

Checking address 78
ISR: enter: Master: abort_transaction
  sending STOP
ISR: enter: ISR: enter: Address not in use.

Checking address 79
ISR: enter: Master: abort_transaction
  sending STOP
ISR: enter: ISR: enter: Address not in use.

Checking address 80
ISR: enter: ISR: enter: Slave device found at address 80

Checking address 81
Master: ERROR timed out waiting for transfer to finish.
Slave device found at address 81

Checking address 82
Master: Cannot start. Transaction still in progress. State: 0. Error code: 0
Master: abort_transaction
  sending STOP
Unexpected error at address 82

Checking address 83
Master: FIFOs not empty in start(). TX: 1 RX: 0
Master: abort_transaction
  sending STOP
Master: ERROR timed out waiting for transfer to finish.
Unexpected error at address 83

Checking address 84
Master: Cannot start. Transaction still in progress. State: 0. Error code: 8
Master: abort_transaction
  sending STOP
Unexpected error at address 84

I notice that it says it Slave device found at address 80 and Slave device found at address 81, which cannot be correct, since I wired my chip to be on address 0 (all address pins to ground).

This is a picture of my setup. WhatsApp Image 2021-05-23 at 21 47 41

I thought maybe my teensy was faulty in some way, tried it with a different controller, but same result!

Maybe this is some regression from other changes we made in #15 ?

Richard-Gemmell commented 3 years ago

Hi Niek, I made another change to the stubck_bus branch which may have been a bad idea. I think the commit that worked well on that branch was https://github.com/Richard-Gemmell/teensy4_i2c/commit/192526f55e9f247b1d4ed4a94062d5e26932aa63. Please give that version a try.

Have you tried this on the version from the master branch? Please try that version and let me know how it's going.

cheers, Richard

niek-dewit commented 3 years ago

On the master branch I get similar logs:

...
Unexpected error at address 118
Master: ERROR timed out waiting for transfer to finish.
Slave device found at address 119
Master: Cannot start. Transaction still in progress. State: 0. Error code: 0
Master: abort_transaction
Unexpected error at address 120
Master: ERROR timed out waiting for transfer to finish.
Slave device found at address 121
Master: Cannot start. Transaction still in progress. State: 0. Error code: 0
Master: abort_transaction
Unexpected error at address 122
Master: ERROR timed out waiting for transfer to finish.
Slave device found at address 123
Master: Cannot start. Transaction still in progress. State: 0. Error code: 0
Master: abort_transaction
Unexpected error at address 124
Master: ERROR timed out waiting for transfer to finish.
Slave device found at address 125
Master: Cannot start. Transaction still in progress. State: 0. Error code: 0
Master: abort_transaction
Unexpected error at address 126
Found 63 slave devices.

I get the above logs when I upload the example to the teensy and it immediately runs. After this is running, and I remove the power source, and plug it back in, the errors change to this:

...
Master: abort_transaction
  sending STOP
Unexpected error at address 120
Master: FIFOs not empty in start(). TX: 1 RX: 0
Master: abort_transaction
  sending STOP
Master: ERROR timed out waiting for transfer to finish.
Unexpected error at address 121
Master: Cannot start. Transaction still in progress. State: 0. Error code: 8
Master: abort_transaction
  sending STOP
Unexpected error at address 122
Master: FIFOs not empty in start(). TX: 1 RX: 0
Master: abort_transaction
  sending STOP
Master: ERROR timed out waiting for transfer to finish.
Unexpected error at address 123
Master: Cannot start. Transaction still in progress. State: 0. Error code: 8
Master: abort_transaction
  sending STOP
Unexpected error at address 124
Master: FIFOs not empty in start(). TX: 1 RX: 0
Master: abort_transaction
  sending STOP
Master: ERROR timed out waiting for transfer to finish.
Unexpected error at address 125
Master: Cannot start. Transaction still in progress. State: 0. Error code: 8
Master: abort_transaction
  sending STOP
Unexpected error at address 126
No I2C slave devices found.

I also tried an implementation with the default Wire library. Which seems to work perfectly fine:


#include <Arduino.h>
#include <Wire.h>

void setup() {
    Wire.begin();
    Wire.setClock(100'000);

    Serial.begin(9600);
    while (!Serial);
}

bool enable_trace = true; // Set to true for more logging
void loop() {
    Serial.println("Searching for slave devices...");

    uint8_t num_found = 0;
    uint8_t buffer[0] = {};
    for (uint8_t address = 0; address < 127; address++) {
        trace("Checking address ", address);

        Wire.beginTransmission(address);
        Wire.write(0);
        Wire.write(0);
        Wire.endTransmission();
        Wire.requestFrom(static_cast<unsigned int>(address), 1);
        delayMicroseconds(100);

        if(Wire.available() == 1) {
            Serial.print("Slave device found at address ");
            Serial.println(address);
            num_found++;
        } else if(Wire.available() == 0) {
            // This is the code we expect if there's nobody listening on this address.
            trace("Address not in use.");
        }

        trace("");
    }
    if (num_found == 0) {
        Serial.println("No I2C slave devices found.");
    } else {
        Serial.print("Found ");
        Serial.print(num_found);
        Serial.println(" slave devices.");
    }
    Serial.println();

    delay(5000);           // wait 5 seconds for next scan
}

void trace(const char* message) {
    if (enable_trace) {
        Serial.println(message);
    }
}

void trace(const char* message, uint8_t address) {
    if (enable_trace) {
        Serial.print(message);
        Serial.println(address);
    }
}

this code gives me the expected outcome. (1 slave device found on address 80) In my first comment, I said it was unexpected to find a slave on 80, but actually it is correct, since the address for the eeprom is prefixed with 01010, only using the last 3 bits for the address. So address "0" is actually address 80. In any case, the code example on the master branch still doesnt seem to work correctly.

When I try the wire/find_slaves example, I am getting strange messages I don't understand, but it does seem to be correct:

...
ISR: enter: ISR: enter: ISR: enter: Master: abort_transaction
  sending STOP
ISR: enter: ISR: enter: ISR: enter: ISR: enter: Slave device found at address 80
ISR: enter: Master: abort_transaction
  sending STOP
...
ISR: enter: ISR: enter: ISR: enter: Master: abort_transaction
  sending STOP
ISR: enter: ISR: enter: ISR: enter: Master: abort_transaction
  sending STOP
ISR: enter: ISR: enter: ISR: enter: Master: abort_transaction
  sending STOP
ISR: enter: ISR: enter: Found 1 slave devices.

If I use the native Wire library example code from before in this post, but replace the wire library with #include <i2c_driver_wire.h>, it also works. Again, a bunch of messages like ISR: enter: ISR: enter: ISR: enter: Master: abort_transaction sending STOP, but it does seem to work.

I noticed that when I change this part in the original raw_find_slaves code example from:

    uint8_t buffer[0] = {};
    for (uint8_t address = 1; address < 127; address++) {
        trace("Checking address ", address);
        master.read_async(address, buffer, 0, true);    // You can use write_async as well
        finish();

to:

    uint8_t buffer[2] = {0, 0};
    for (uint8_t address = 1; address < 127; address++) {
        trace("Checking address ", address);
        master.write_async(address, buffer, 2, true);    // You can use write_async as well
        finish();

Then the output is as follows:

...
ISR: enter: ISR: enter: Master: abort_transaction
  sending STOP
ISR: enter: ISR: enter: Unexpected error at address 78
ISR: enter: ISR: enter: Master: abort_transaction
  sending STOP
ISR: enter: ISR: enter: Unexpected error at address 79
ISR: enter: ISR: enter: ISR: enter: ISR: enter: Slave device found at address 80
ISR: enter: ISR: enter: Master: abort_transaction
  sending STOP
ISR: enter: ISR: enter: Unexpected error at address 81
ISR: enter: ISR: enter: Master: abort_transaction
  sending STOP
ISR: enter: ISR: enter: Unexpected error at address 82
ISR: enter: ISR: enter: Master: abort_transaction
  sending STOP
...
  sending STOP
ISR: enter: ISR: enter: Unexpected error at address 123
ISR: enter: ISR: enter: Master: abort_transaction
  sending STOP
ISR: enter: ISR: enter: Unexpected error at address 124
ISR: enter: ISR: enter: Master: abort_transaction
  sending STOP
ISR: enter: ISR: enter: Unexpected error at address 125
ISR: enter: ISR: enter: Master: abort_transaction
  sending STOP
ISR: enter: ISR: enter: Unexpected error at address 126
Found 1 slave devices.

Which is more like what I would expect. Still a lot of "unexpected error" messages, but at least it finds only 1 slave at the expected address.

Richard-Gemmell commented 3 years ago

Thanks for this Niek. I've tweaked raw_find_slaves.ino so it works for me.

While I was fiddling with the code I noticed that a correct version works sometimes but not always. Then I noticed that if I disconnect the board and then power it up again it always works.

I suspect that the slave device is getting stuck. Presumably it remains powered up while the Teensy is being reprogrammed but doesn't reset.

Please try this version of raw_find_slaves.ino but power cycle the board after reprogramming. The find_slaves.ino example also works for me.

I tested both with the master branch.

niek-dewit commented 3 years ago

Thanks! It works for me too now :)