Description
Describe the bug
When STM32 is I2C master, any beginTransmission(x)
call for x like 0b1111 0xxx
without write()
call in between will cause subsequent endTransmission()
call to return I2C_NACK
, despite slave device sending ACK on SDA line.
This is due to the fact that STM32 automatically detects addresses starting with 0b1111 0xxx
as 10 bit addresses, and in that case, does not set I2C_FLAG_ADDR
flag which is being checked after sending the first byte of address.
Arduino_Core_STM32/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c
Lines 3578 to 3605 in 5e4f220
To Reproduce
I2C master code:
#include <Arduino.h>
#include <Wire.h>
HardwareSerial Serial1(PA10,PA9);
void setup() {
Serial1.begin(115200);
Wire.begin();
}
void loop() {
Wire.beginTransmission(0x79);
//Wire.write(1); //uncomment to receive ACK, but receive garbage on the other end
int result = Wire.endTransmission();
Serial1.println(result);
delay(1000);
}
I2C slave code:
#include <Arduino.h>
#include <Wire.h>
HardwareSerial Serial1(PA10,PA9); //remove when testing on Arduino
void handleData(int bytes){
byte data = Wire.read();
Serial1.println(data); //change to Serial if testing on Arduino
}
void setup() {
Serial1.begin(115200); //change to Serial if testing on Arduino
Wire.begin(0x79);
Wire.onReceive(handleData);
Serial1.println("Starting"); //change to Serial if testing on Arduino
}
void loop() {
}
Steps to reproduce the behavior:
- Connect STM32F103C8T6 (I2C Master) to another STM32F103C8T6/Arduino (I2C slave). (GND,SDA,SCL, RX/TX lines)
- Program STM32F103C8T6 as I2C master, another one/arduino as I2C slave.
- I2C master will report NACK despite having received ACK from slave device.
Additionally, if you uncomment Wire.write(1)
call in I2C master code, I2C slave will report receiving a 242
byte, but only once and won't report again until reset.
This causes a simple example of I2C scanner ineffective for those addresses and ultimately makes communciation with those addresses impossible without modifying underlying framework's core code.
Expected behavior
I2C master should report ACK. With additional Wire.write()
call uncommented, a slave device should report receiving 1
every one second.
Metadata
Metadata
Assignees
Type
Projects
Status