I2C Device Address in Search Macro

I posted this on GitHub previously, but seems like this is a better place for discussing firmware changes/features.

On BP3, the I2C search macro would show the 7 bit device address in parenthesis next to the 8 bit read and write addresses:

i2c_bp3

Running the search macro on BP5 against the same device only returns the R/W addresses and not the device address itself:

i2c_bp5

Looking at the printf line in hwi2c.c, this appears to be intentional and not a bug.

I would propose that showing the base device ID in the search mode, while not technically necessary, makes for a more predictable experience as users will likely be more familiar with referencing the device in their code by the 7 bit address. This could be especially confusing in a situation where you have multiple I2C devices on the bus.

Good catch! Thank you. I’m debugging another issue in I2C this morning and will make that change.

I’m sorry, I don’t get notifications from github because of a “load bearing laptop” kind of situation with my old email addresses. I only catch things when I visit the site. I want to get it straightened out, but it’s going to be a whole ordeal.

image

Updated. A new firmware should post shortly. Thanks again for the suggestion.

Just tested new build, and base addresses now showing. Much appreciated.

Now, I know this is really splitting hairs, but could we get a newline after a detected device to make a busy bus a bit easier to parse visually?

bp5_multi

Looking at the code, I suppose this is easier said than done. Ideally the R/W addresses for each device would be on the same line, but looks like there would need to be some logic added to determine whether or not an ack is from a new device entirely, or just half of the R/W pair.

image

Nice idea, thank you for the suggestion. I did a few evolutions and came up with this.

image

This is how it looks with a single address device (the si7021 from yesterday).

I’ll push this, but please let me know if you think of any changes. It’s such a used part of the code it should really be nice.

Really like this, the alternating colors is great idea to make them visually more distinct from each other.

The only other thought I would have, and I guess this is really getting more into personal preference than anything now, is to perhaps print the base ID first and then the R/W addresses.

So instead of:

0xEC(0x76 W) 0xED(0x76 R)

It would show as:

0x76 (0xEC W) (0xED R)

That way you’re not printing the base twice, and also leading with the more recognizable of the addresses. On the other hand, the BP has always shown I2C addresses the same way, and changing it now might mess up existing documentation.

Oh, I like that. I’ll see what I can do to make it more succinct.

I’m also going to look over the 1-wire scanner and see if there’s anything we can do to make it extra as well. I believe it has a sizable database of part/family IDs, but I wrote that a while ago.

That’s an interesting thought – including a community-sourced collection of common I2C addresses so the scanner can make a guess at what the detected device might be.

Maybe it could be implemented with an array of description strings, that way it would be easy for others to add addresses. They would just need to add a new plain-text line to the end of array and not have to get bogged down with code (it seems like the 1-wire scanner in BP3 firmware is using #define and switch/case).

In general my skill level in C could probably be best described as “Enough to Hurt Myself”, but maybe something like:

// Device List
const char i2c_devices[][32] =
{
    "0x76 BME260 Enviro Sensor",
    "0x3C SSD1306 OLED Display"
};

const char * print_desc(int dev_id)
{
    // Convert int to 7-bit hex address
    char hex_id[5];
    sprintf(hex_id, "0x%02X", dev_id>>1);

    // Loop through array
    for(int i = 0 ; i < (sizeof(i2c_devices) / sizeof(i2c_devices[0])); i++)
        // Check if array entry contains ID
	    if(strstr(i2c_devices[i], hex_id) != NULL)
	       // Return first match, offset to hide ID
	       return (i2c_devices[i] + 5);

    // Hack - Return blank line if not found to avoid undefined behavior
    return " ";
};

...

 printf("0x%02X (0x%02X %c) %s", i>>1, i, ((i&0x1)?'R':'W'), print_desc(i));

So if i is 120, the output should be:

0x3C (0x78 W) SSD1306 OLED Display

Would need to be adapted to how you’re getting the R/W pair, but you get the idea.

1 Like

I like this idea to get a rough overview of all chips used on a bus.

But please make in fully configurable:

  • Config option to disable the lookup.
  • File with a list of addresses and names on the flash, editable via usb
    ( if no file is there, to use a basic subset hardcoded in the firmware is fine for me)
2 Likes

Oh, I like the file database idea.

I should definitely be a separate command. It will probably generate a ton of output, there’s not a very big name space and some seem really commonly used.

How about variants? A 24LC has a bunch of part numbers and I think they’re pretty similar in responding to multiple same addresses.

Here’s two pretty extensive lists. I guess adafruits is the way to go because it’s in git and probably tended to a bit?

I forgot all about the ability to put stuff like this on the BP5’s flash storage – definitely easier to maintain than having to actually edit the source code just to add devices.

That said, by using the list of addresses Adafruit has already compiled, can just pull that in occasionally and not have to worry about it.

Is it generally agreed the adafruit list is the way to go? If so, I’ll hack together some scripts and play with importing it.

1 Like

Adafruits list was the way to go because it has an explicit license. I wrote a script to parse it and got it going last night. I’m fighting an off by one error, but it’s almost done.

The other list has MORE parts (not just stuff adafruit sells), and can be downloaded as a json file. However the content is unlicensed. This may be a better option for download yourself and save to flash. I also wrote to get clarification on the license.

I’ll have a test soon and would appreciate any feedback on the formatting of results.

You could provide a sample database with common I2C addresses, perhaps with some commented out with a “#” that would give people a start in customizing.

image

Updated list with base address, then write and read. If you check out the code, this update made everything nice and clean.

image

New macro (5) (temporary, check (0) macro list for current position) uses the Adafruit I2C list to identify devices. I parsed it and some info (like the 24LC chip I’m scanning) didn’t get included because it’s not entered systematically. It takes up about 12K in flash (of 16megabytes), and contains mostly things adafruit sells.

This would be a better list I think (drop them an note and ask about the content license). If we eventually have it scan from the JSON file you can download from that site, it also includes datasheet/digikey/adafruit/sparkfun links which would be kind of killer.

If we get permission to use the larger database in the actual firmware, do you think it should include the part number AND the brief description? I feel like it should, even if the description is cropped to 10 or 12 characters.

According to the About page, the data is licensed under MIT:

https://i2cdevices.org/about

The source code for the directory

The actual site source code is available at github, but it does not include the database as far as I can tell. You can grab the whole database as JSON, and there’s the argument to be made that you can’t copyright the fact that certain parts have certain properties. My guess - it’s intended to be open source. I’ve written their contact form though, I like to be sure before I start hoovering up others’ projects.

One sure thing is let users download and save the database to the flash themselves, that side steps the whole issue I guess.

To me, it just seems like they worded it strangely. The heading above it says “Open Source, Open Data” – the intent at least is clear. But you’re right that it’s the kind of thing that should be confirmed before it gets combined with another project.

Open Source, Open Data

Oh man, you’re totally right. Thanks for pointing that out, I feel dense. The intent is defo clear from that.