Closed blazej222 closed 2 weeks ago
Hi @blazej222 For me ther is no error: https://www.i2c-bus.org/addressing/
The address you used rely on the 10 bits addressing: 1111 0xxx
Moreover this is the HAL and hardware which handle that so nothing could be done here. If you really think it is an issue (don't think so) you can file an issue on the STMicroelectronics GitHub organization. Mainly on STM32CubeF1 repository.
My apologies, I might have worded this issue badly.
Let's assume we have a slave device on I2C that has a 10bit address of 0x208
(010 0000 1000
).
To communicate with the device, the following two bytes must appear on I2C bus (as seen with oscilloscope): 0xF2 0x08
(1111 0010 0000 1000
).
Normally on arduino, you can communicate with this device simply by doing something like this:
Wire.begin(0x79);
Wire.write(0x08);
//insert additional communication here
Wire.endTransmission()
However, when using the same code on STM32Duino this communication won't succeed.
First of all, 0xF2
(0x79 << 1
) byte will appear twice on the bus (because we are configuring HAL's I2C interface in 7bit mode, however the MCU itself recognizes this address as the beginning of 10 bit address).
As 10bit mode uses different flags than 7bit mode(for example, it doesn't set the I2C_FLAG_ADDR
flag HAL's checking for) it produces glitchy results in the communication.
As a result, there's no proper way to communicate with devices that use 10bit addressing from STM32duino.
The problem itself isn't present in HAL library - on native STM32 cube all you have to do is configure the interface into I2C_ADDRESSINGMODE_10BIT
and the communication will be handled properly.
I understand that Arduino library does not explicitly provide 10bit addressing support - however, on native Arduino library it's possible to communicate with 10bit I2C devices by simply splitting the address into two bytes. In case of STM32duino it's not possible to communicate at all.
Probably a check would have to be implemented in STM32duino that configures HAL into 10bit addressing mode when applicable.
Hi @blazej222 OK thanks for the feedback so your request is to have 10 bits address support. Currently, the Wire library support only 7 bits address.
Ref: https://www.arduino.cc/reference/en/language/functions/communication/wire/
Describe the bug When STM32 is I2C master, any
beginTransmission(x)
call for x like0b1111 0xxx
withoutwrite()
call in between will cause subsequentendTransmission()
call to returnI2C_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 setI2C_FLAG_ADDR
flag which is being checked after sending the first byte of address.https://github.com/stm32duino/Arduino_Core_STM32/blob/5e4f22065273339bbd74c01b8209e9592d2c30bd/system/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c#L3578-L3605
To Reproduce
I2C master code:
I2C slave code:
Steps to reproduce the behavior:
Additionally, if you uncomment
Wire.write(1)
call in I2C master code, I2C slave will report receiving a242
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 receiving1
every one second.