STM32F4x1 BlackPill issue with I2C as slave

camelator
Posts: 12
Joined: Fri Aug 20, 2021 10:27 am

STM32F4x1 BlackPill issue with I2C as slave

Post by camelator »

Hi all,
I am facing issue using I2C as slave: I can not make it work and see from Jetson Nano.
All lines have pull up resistors.
It is not an issue with Jetson Nano as my servo controller is perfectly detected.
But my black pill is not detected.
I also have error message on the jetson nano found with dmesg command:
[ 7843.509985] tegra-i2c 7000c400.i2c: pio timed out addr: 0x4 tlen:12 rlen:4
[ 7843.517357] tegra-i2c 7000c400.i2c: --- register dump for debugging ----
[ 7843.527385] tegra-i2c 7000c400.i2c: I2C_CNFG - 0x22c00
[ 7843.533331] tegra-i2c 7000c400.i2c: I2C_PACKET_TRANSFER_STATUS - 0x10001
[ 7843.540243] tegra-i2c 7000c400.i2c: I2C_FIFO_CONTROL - 0xe0
[ 7843.546020] tegra-i2c 7000c400.i2c: I2C_FIFO_STATUS - 0x800080
[ 7843.552002] tegra-i2c 7000c400.i2c: I2C_INT_MASK - 0x7d
[ 7843.557351] tegra-i2c 7000c400.i2c: I2C_INT_STATUS - 0x2
[ 7843.562806] tegra-i2c 7000c400.i2c: i2c transfer timed out addr: 0x4
[ 7853.749749] tegra-i2c 7000c400.i2c: pio timed out addr: 0x5 tlen:12 rlen:4


Any help is welcome!

Many thanks guys!




Here is my code:

Code: Select all

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

#define SLAVE_SDA PB7
#define SLAVE_SCL PB6
#define SLAVE_ADR 0x4

TwoWire slaveI2C (SLAVE_SDA,SLAVE_SCL) ;

void receiveEvent (int) ;

void setup() {
  // put your setup code here, to run once:

  Serial.begin(115200) ;
  slaveI2C.setClock(400000) ;
  slaveI2C.begin(SLAVE_ADR) ;
  slaveI2C.onReceive(receiveEvent) ;
    
}

void loop() {

  while (true) {
    delay(100) ;
  }
}

void receiveEvent (int howMany) {
  if (slaveI2C.available()<1) 
    return ;
  uint8_t command=slaveI2C.read() ;
}
User avatar
fpiSTM
Posts: 1738
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: STM32F4x1 BlackPill issue with I2C as slave

Post by fpiSTM »

Hi @camelator

Nice to see you here. ;)
I've tested with 2 weact blackpill F411CE.
One with the I2C scanner example (https://github.com/stm32duino/Arduino_C ... canner.ino) with speed set to 400kHz and one with your code that I've cleaned and use the default Wire instance which are already on PB7/PB6:

Code: Select all

#include <Wire.h>

#define SLAVE_ADR 0x4

void receiveEvent (int) ;

void setup() {
  Serial.begin(9600) ;
  Wire.setClock(400000) ;
  Wire.begin(SLAVE_ADR) ;
  Wire.onReceive(receiveEvent) ;
}

void loop() {
}

void receiveEvent (int howMany) {
  (void)howMany;
  while (Wire.available()){
    Serial.println((char)Wire.read());
  }
}
I've connected a shield with two I2C devices (1 eeprom and 1 temperature sensor) in order to have the pullup resistors on each I2C line and the board with your updated code on the same I2C lines. The result is correct:
Scanning...
I2C device found at address 0x04
I2C device found at address 0x48
I2C device found at address 0x50
done
Scanning...
I2C device found at address 0x04
I2C device found at address 0x48
I2C device found at address 0x50
done
Scanning...
I2C device found at address 0x04
I2C device found at address 0x48
I2C device found at address 0x50
done
We can see the salve device @0x04, the two others are the devices from the shield.

I don't know the Jetson Nano hardware nor software, anyway I guess the i2cdetect is based on the linux one.
Looking at the man of I2Cdetect: https://linux.die.net/man/8/i2cdetect
Warning
This program can confuse your I2C bus, cause data loss and worse!
camelator
Posts: 12
Joined: Fri Aug 20, 2021 10:27 am

Re: STM32F4x1 BlackPill issue with I2C as slave

Post by camelator »

Hi many thanks for your answer.
It is a surprise to me you successfully done the I2C connection with the default Wire instance.
as you can see below, I drove a lot of tests, and non of them are working with the default Wire instance.
I had few results with dedicated TwoWire instance (PB7,PB6) but never at address 4,48 and 50. And why these address ? I can understand 4... But the others?

Maybe there are some difference of parameters in board selection?
Here is what I have:
"Generic STM32F4 series"
"blackpill F411CE"

I have to add that my blackpill is not weact but this one which has good reviews as well (5 stars):
https://fr.aliexpress.com/item/40011578 ... 6c374v2gIM

Here are some conclusions about detection programs:

A/ Jetson nano as master // STM32 as slave -> KO
B/ Jetson nano // servo controller as slave -> perfect
C/ STM32 as master // servo controller as slave -> OK (with custom TwoWire instance) for 5 minutes
D/ STM32 as master // STM32 as slave -> OK (with custom TwoWire instance) for 5 minutes

never succed to have the blackpill as slave detected by the jetson nano. Every time I have the same errors.
I am going more deep tests with an ESP32 board which I know is correctly detected by Jetson Nano as well as my servo controller.

Maybe you have more ideas about:
1/ the differences between your results and my results - using the default Wire instance - and why the address detected are not the same, and in your situation why 3 occurences?

2/ other assumptions about the errors?

Regards,

Christian





Here is whet I've done:

A/ Jetson nano // STM32 as slave

1/ manually redefine SDA and SCL

- error message with dmesg and timeout issues as I previously described

2/ use the default wire constant
- no errors but no detection.

B Jetson nano servo controller as slave

perfectly detected

C/ STM32 as master // servo controller as slave


1/ custom TwoWire instance (change the SDA and SCL values to B7 and B6) => Working 5-10 minutes (probably because of multiple input power and USB power)

serial console is :
« Scanning…
I2C device found at address 0x40 !
I2C device found at address 0x70 !
Done
« 

but after 5-10 minutes : « Scanning No I2C devices found » → I have to reset the STM32


2/ use the default wire constant => Not working

- errors message : « Unknown error at address 0xxx » where xx is from 01 to 0x7e
- No I2C devices found



C/ STM32 as master // STM32 as slave

1/ STM32 as master : use default Wire, STM32 as slave : use default wire
2/ STM32 as master : use default Wire, STM32 as slave : use custom wire
3/ STM32 as master : use custom Wire, STM32 as slave : use default wire

1/ STM32 as master : use default Wire, STM32 as slave : use default wire
Scanning…
No I2C device found

2/ STM32 as master : use default Wire, STM32 as slave : use custom wire
Scanning…
No I2C device found

3/ STM32 as master : use custom Wire, STM32 as slave : use custom wire

Scanning…
I2C device found at address 0X04 !
Done





here is the code used :

#include <Wire.h> //include Wire.h library

void setup()
{
Wire.begin(); // Wire communication begin
Serial.begin(9600); // The baudrate of Serial monitor is set in 9600
while (!Serial); // Waiting for Serial Monitor
Serial.println("\nI2C Scanner");
}

void loop()
{
byte error, address; //variable for error and I2C address
int nDevices;

Serial.println("Scanning...");

nDevices = 0;
for (address = 1; address < 127; address++ )
{
// The i2c_scanner uses the return value of
// the Write.endTransmisstion to see if
// a device did acknowledge to the address.
Wire.beginTransmission(address);
error = Wire.endTransmission();

if (error == 0)
{
Serial.print("I2C device found at address 0x");
if (address < 16)
Serial.print("0");
Serial.print(address, HEX);
Serial.println(" !");
nDevices++;
}
else if (error == 4)
{
Serial.print("Unknown error at address 0x");
if (address < 16)
Serial.print("0");
Serial.println(address, HEX);
}
}
if (nDevices == 0)
Serial.println("No I2C devices found\n");
else
Serial.println("done\n");

delay(5000); // wait 5 seconds for the next I2C scan
}
User avatar
fpiSTM
Posts: 1738
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: STM32F4x1 BlackPill issue with I2C as slave

Post by fpiSTM »

camelator wrote: Fri Aug 20, 2021 2:47 pm I had few results with dedicated TwoWire instance (PB7,PB6) but never at address 4,48 and 50. And why these address ? I can understand 4... But the others?
Seriously, I've told you that I used a shield with 2 I2C devices... so... this is the @ of those 2 devices...
camelator wrote: Fri Aug 20, 2021 2:47 pm Maybe there are some difference of parameters in board selection?
Here is what I have:
"Generic STM32F4 series"
"blackpill F411CE"
I use this one as it was added by a contributor for the WEact one.
camelator wrote: Fri Aug 20, 2021 2:47 pm I have to add that my blackpill is not weact but this one which has good reviews as well (5 stars):
https://fr.aliexpress.com/item/40011578 ... 6c374v2gIM
The weact black pill have a 25MHz xtal for HSE, it seems the one you point also. Anyway you should check this.
You should try the I2C scanner with your board.

For the I2C instance, I remember why it does not work on your side. There is a mistake in the variant definition, I2C SDA pin is wrong: https://github.com/stm32duino/Arduino_C ... ssues/1369
Fix is here: https://github.com/stm32duino/Arduino_C ... c15b4f93be

For all other issues you met, I would check if something is wrong with the hardware.
Pull up resistors on each I2C lines ? Wire are not too long? ...
ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: STM32F4x1 BlackPill issue with I2C as slave

Post by ag123 »

not too sure about this, but while debugging, it probably helps to have a secondary channel e.g. uart or swo or even usb (i.e. usb serial).
so that you can print 'debug' messages across the alternate channel.
if it freezes on the i2c slave stm32, the question would then be did your 'debug' messages from the same mcu freeze as well?
if both channels freezes, then there is a chance a hardfault or something (perhaps out of memory?) has occurred

of course a logic analyzer probably help, there is one here, pretty 'old' and pretty much forgotten, it turns a stm32f401,411 black board into a simple logic analyzer.
viewtopic.php?f=10&t=116
camelator
Posts: 12
Joined: Fri Aug 20, 2021 10:27 am

Re: STM32F4x1 BlackPill issue with I2C as slave

Post by camelator »

Seriously, I've told you that I used a shield with 2 I2C devices... so... this is the @ of those 2 devices...
Ok.
The weact black pill have a 25MHz xtal for HSE, it seems the one you point also. Anyway you should check this.
You should try the I2C scanner with your board.
Checked. It is a 25MHZ scanner... as you can see below, I also drove other tests with the same results.

For the I2C instance, I remember why it does not work on your side. There is a mistake in the variant definition, I2C SDA pin is wrong: https://github.com/stm32duino/Arduino_C ... ssues/1369
Fix is here: https://github.com/stm32duino/Arduino_C ... c15b4f93be
Ok.
For all other issues you met, I would check if something is wrong with the hardware.
Pull up resistors on each I2C lines ? Wire are not too long? ...
everything was double checked.

I drove other tests, with ESP32. With exactly the same 2 programs we are discussing as of now.

Here are the results for all the tests:

boards used:
blackpill 1
https://fr.aliexpress.com/item/40011578 ... 6c374v2gIM

blackpill 2
https://www.aliexpress.com/item/4001062 ... 4c4dzOqoeP

ESP32
Nvidia Nano


A/ Jetson nano as master // blackpill 1 as slave -> KO
B/ Jetson nano // servo controller as slave -> perfect
G Jetson Nano as master // blackpill 2 as slave KO (same error)
H Jetson nano as master / ESP32 as slave OK

C/ blackpill 1 as master // servo controller as slave -> OK (with custom TwoWire instance) for 5 minutes
D/ blackpill 1 as master // blackpill 1 as slave -> OK (with custom TwoWire instance) for 5 minutes
E/ blackpill 1 as master // blackpill 2 as slave OK

F/ ESP32 as master // blackpill 2 as slave OK

So definitely it looks like an issue between Jetson nano and black pill.... Don't know why...
User avatar
fpiSTM
Posts: 1738
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: STM32F4x1 BlackPill issue with I2C as slave

Post by fpiSTM »

camelator wrote: Sun Aug 22, 2021 8:08 pm So definitely it looks like an issue between Jetson nano and black pill.... Don't know why...
Yes but I have no more clue. If you have a logic analyzer you should check I2C signals to see what's going wrong.
What is the reference voltage for the Jetson nano? For STM32 it is 3.3v.
camelator
Posts: 12
Joined: Fri Aug 20, 2021 10:27 am

Re: STM32F4x1 BlackPill issue with I2C as slave

Post by camelator »

Jetson Nano is 3.3v.
I just put a logic analyser and here is what I've found:

- Having pull-up resistors on both SDA and SCL lines.
- Having a servo controller on the I2C lines

1/ Without blackpill
data recorded by the logic analyser shows SDA and SCL at high stage.
This is aligned with the I2C specifications

2/ Having blackpill connected on the I2C line
data recorded by the logic analyser show SDA at high stage but SCL at low stage.

This is not aligned with the I2C specifications
This is why there is a problem on the jetson nano side

I double checked the pull up resistors, They work perfectly 4.7K

do you know where this low stage comes from?
User avatar
fpiSTM
Posts: 1738
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: STM32F4x1 BlackPill issue with I2C as slave

Post by fpiSTM »

Clock stretching ? bad resistor value? maybe jetson enable some PU on the line ? ...
camelator
Posts: 12
Joined: Fri Aug 20, 2021 10:27 am

Re: STM32F4x1 BlackPill issue with I2C as slave

Post by camelator »

With the following errors I am sure we can avoid Jetson nano issues:

I removed the Jetson Nano from the I2C lines.

I had these two experiences:

1/ Blackpill configured as slave:
put the logic analyser on pins PB7 and PB6 (SDA and SCL)
SDA HIGH
SCL LOW

2/ Blackpill configured as slave with pullup resistors (3.3V, 4.7K) (of course ground linked together)
SDA HIGH
SCL LOW

=> I never ask for special clock adjustment on the STM32 side.
reistors value were double checked but as you can see :
it is not a resistor issue
it not comes from Jetson nano

my code is the following one:

#include <Wire.h>

#define SLAVE_ADR 0x4

void receiveEvent (int) ;

void setup() {
Serial.begin(9600) ;
Wire.setClock(400000) ;
Wire.begin(SLAVE_ADR) ;
Wire.onReceive(receiveEvent) ;
}

void loop() {
}

void receiveEvent (int howMany) {
(void)howMany;
while (Wire.available()){
Serial.println((char)Wire.read());
}
}
Post Reply

Return to “STM32F4 based boards”