Operation of the STM32U585 MCU's I2C buses on the header pins

1. I2C bus marked as SDA/SCL on the header pins works well with Wire.h Library and Wire.begin(). In both STM and Arduino documentation Fig-1), it is shown as I2C2. I have tested the functionality of the bus using I2C Slave Address Scanner Sketch (4.) and MCP4725 DAC (Fig-2). The DAC is found at correct slave address 0x60. The DAC breakout board contains 2x4.7k pull-up resistors.

2. Arduino documentation (Fig-1 below) has shown another I2C3_SDA/SCL bus as alternate function of A4/A5. I have connected the DAC at this bus and ran the scanner sketch, but I could not find its presence on the bus with Wire.h and Wire.begin()/Wire1.begin()/Wire2.begin(). (Wire3.begin() is not accepted.)

3. I could not check I2C4 bus due to lack of Qwiic connector.

4. This is the I2C Slave Address Scanner Sketch:

#include<Wire.h>
byte busStatus;

void setup()
{
  Serial.begin(9600);
  Wire.begin();
  for (int i2cAddress = 0x00; i2cAddress <= 0x7F; i2cAddress++)
  {
    Wire.beginTransmission(i2cAddress);
    busStatus = Wire.endTransmission();
    if (busStatus == 0x00)
    {
      Serial.print("I2C Device found at address: 0x");
      Serial.println(i2cAddress, HEX);
    }

    else
    {
      Serial.print("I2C Device not found at address: 0x");
      Serial.println(i2cAddress, HEX);
    }
  }
}

void loop()
{

}

5. Arduino Document (partial)


Figure-1:

6. MCP4725 DAC Breakout Board


Figure-2:

Would be glad to receive help for the operation of the above DAC using I2C3 bus onA4/A5 pins.

Although physically routed, for some reason pins A4 and A5 are not mapped to and I2C function within the Arduino Zephyr core. I2C3 can apparently be made available by modifying the core overlay and creating a variant, which will require messing with the core files. Perhaps someone will be able to share the details of how this can be done. Unless there is a spacific reason for needing to use pins A4/A5, it might be less hassle to just use the QWIIC port or the header pins that you have already identified as being functional.

See this post

Ok!

Now, I know from the forum members that there are no simple Arduino APIs to activate the I2C3 bus on A4/A5 pin like Serial1.begin() API which activates a functional UART Port on D0/D1 pins on the header.

Being inspired by Srerial1.begin() API, I have thought that the simple Wire3.begin() will activate the I2C3 bus; but, it is NOT.

Thank you for taking care of my post.

Just to confirm that Wire1.begin() does work fine on the QWIIC connector/port.

  • I2C Bus on QWIIC Connector is described as I2C4 in Arduino/STM documentation.
  • I2C4_SDA/SCL signal from internal I2C4 interface (Fig-1) can be routed to these pins of the MCU: N6/L6, L9/K9, K12/K10, F5/B5

I wish to know which two pins of the above do carry I2C4_SDA/SCL signals onto QWIIC connector (Fig-1)?


Figure-1:

Think you misunderstand. Wire2 has been available for the last couple of releases. To "activate" it just use Wire2.begin and now you can use A4/A5 as Wire2.

Just to show more info if you look at the pinout you see A4/A5 as PC1/PC0

and if you look at the STM32 overlay you see that i2c3 is defined as

&i2c3 {
	status = "okay";
	zephyr,deferred-init;
	pinctrl-0 = <&i2c3_scl_pc0 &i2c3_sda_pc1>;
	pinctrl-names = "default"; 
	clock-frequency = <I2C_BITRATE_FAST>;
};

and i2c is wire is setup as

i2cs = <&i2c2>, <&i2c4>, <&i2c3>;

i.e., Wire, Wire1 and Wire2

So yes Wire2 is available as well.

I tried using Wire.h and Wire2.begin() for the I2C bus on A4/A5 pin. The DAC was not found.

Your wire scanner test is hard coded to Wire. That is you not only need to have Wire2.begin, you also need to change the other references to Wire2 as well.

Something like:

#include<Wire.h>
byte busStatus;

void setup()
{
  Serial.begin(9600);
  Wire2.begin();
  for (int i2cAddress = 0x00; i2cAddress <= 0x7F; i2cAddress++)
  {
    Wire2.beginTransmission(i2cAddress);
    busStatus = Wire2.endTransmission();
    if (busStatus == 0x00)
    {
      Serial.print("I2C Device found at address: 0x");
      Serial.println(i2cAddress, HEX);
    }

    else
    {
      Serial.print("I2C Device not found at address: 0x");
      Serial.println(i2cAddress, HEX);
    }
  }
}

void loop()
{

}

You have just got it at the right point--- my objects were Wire and were not changed to Wire2 during begin/endTransmission.

Now, the DAC is found at 0x60.

Wise man of the west has offered a beautiful gift to the poor fellow of the east!

Not sure about Wise, but been around the block a few times :laughing:

Now @Merlin513 and I often have wire scanners, that are setup to handle all of the busses on a board.

I just hacked up my previous version to make it more automatic in knowing how many wire buses there are on the zephyr board...

zephyr_wire_scanner-261020a.zip (2.8 KB)

Nice update @KurtE - that makes it easier. Not sure why you have sdram test included - looks like something I do.

Just to let you know about the wire scanner we use - its based off of something we have been using on the Teensy for years and besides printing out device addresses it will also print out device name if its in the list of devices, i.e.,

void printKnownChips(byte address)
{
  // Is this list missing part numbers for chips you use?
  // Please suggest additions here:
  // https://github.com/PaulStoffregen/Wire/issues/new
  switch (address) {
    case 0x00: Serial.print(F("AS3935")); break;
    case 0x01: Serial.print(F("AS3935")); break;
    case 0x02: Serial.print(F("AS3935")); break;
    case 0x03: Serial.print(F("AS3935")); break;
    case 0x04: Serial.print(F("ADAU1966")); break;
    case 0x0A: Serial.print(F("SGTL5000")); break; // MCLK required
    case 0x0B: Serial.print(F("SMBusBattery?")); break;
    case 0x0C: Serial.print(F("AK8963")); break;
    case 0x10: Serial.print(F("CS4272, BMM150")); break;
    case 0x11: Serial.print(F("Si4713")); break;
    case 0x13: Serial.print(F("VCNL4000,AK4558")); break;
    case 0x18: Serial.print(F("LIS331DLH")); break;
    case 0x19: Serial.print(F("LSM303,LIS331DLH")); break;
    case 0x1A: Serial.print(F("WM8731")); break;
.....

Of you course if device is not listed you can always add it.

The sketch of your zip file has detected my DAC as Wire2.

Updated zip file in previous post, as there was some detritus of files in that directory, which luckily @Merlin513 found.

Thanks for posting that sketch.

Thank you for that information. It seems some of the information out there may be out of date.

Why is it like this in the following table? I mean that hardware bus name does not do one-to-one orrespondance with sofware object name. I2C3 has the object named Wire2 and not Wire3; I2C3 has the object amed Wire2. Where is the I2C1?

Object -------------> Wire      Wire1      Wire2        Wire3         Wire4
Bus
|
|
v
I2C1
I2C2 (SDA/SCL) ------ x
I2C3 (A4/A5)  ---------------------------- x                 
I2C4 (QWIIC) ------------------- x

@KurtE Thanks for the sketch. Just a quick question.

in setup() and the following:

#if WIRE_HOWMANY >= 3
  Wire2.begin();
  Wire1.setClock(100000);
#endif

Why use Wire1.setClock(100000) and not Wire2, any particular reason?

Thanks.

Ok now you getting down into the guts of the STM32 processor itself and how you go from manufacturers reference manual to actual implementation.

Essentially, n Zephyr, the names you see in a device tree overlay such as &i2c3 do not necessarily match the physical Arduino header names. They refer to the MCU's internal peripheral instance numbering. From the reference manual (section 65) you will see the i2c numbering on the processor

Basically what you seeing when you look at the board overlay and if you dive down deeper the dts file in zephyr for the Q is the mapping from the MCU through to the Arduino environment.

What the Wire library does as well as the core is an abstraction layer from the Zephyr to Arduino which we are all useful.

Hope this helps somewhat. Probably could write a book on this but not fully qualified for that - hopefully someone will jump in and explain more.

Should be wire2 - a typo have to check my version as well.

Glad I am not the only one having finger trouble :grin: . Thankyou.