Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I2C SDA line stuck low after requestFrom with more than 1 byte - No I2C Stop sequence generated #2064

Closed
yec23 opened this issue Jul 11, 2023 · 18 comments

Comments

@yec23
Copy link

yec23 commented Jul 11, 2023

Describe the bug
I2C SDA line stuck low after requestFrom with more than 1 byte. Master seems to not generate the I2C Stop sequence.
Same result in normal or fast mode.
Working ok when requesting 1 byte
Same hardware and code run well when compiled with Roger Clark environment on Arduino IDE 1.8 Linux.

To Reproduce

  • Wire.requestFrom with two bytes or more return ok but SDA remains low. Adding stop parameter (true) has same behaviour (argument defaulted to true)
  • I2C Registers after begin() and before requestFrom() call:
    CR1: 1
    CR2: 0x24
    SR1: 0
    SR2: 0
    After requestFrom() call:
    CR1: 0xA01 => POS and STOP set
    CR2: 0x424 => ITBUFEN set
    SR1: 0x240 => ARLO and RxNE set
    SR2: 2 => BUSY set
  • Successive requestFrom then end in error.
  • Only a end() and begin() resume I2C state.

Steps to reproduce the behaviour:
see code attached
Sourcecode.txt

Screenshots
With Arduino Core STM32: no I2C STOP generated
image

With Roger Clark, I2C STOP generated
image

Desktop (please complete the following information):

  • OS: Windows 10
  • Arduino IDE version: 2.1.0
  • STM32 core version: 2.6.0
  • Tools menu settings if not the default: USB support: CDC (generic serial supersede U(S)Art), U(S)ART support Enable (generic serial)
  • Upload method: SWD

Board (please complete the following information):

  • Name: Blue PillF103CB 128k
  • Extra hardware used if any: MPU-6050 slave

Additional context
First version of the project was implemented with Roger Clarck STM32 environment. Project is being migrated to Arduino Core STM32 before implementing new features.

@fpistm
Copy link
Member

fpistm commented Jul 11, 2023

Hi @yec23
Thanks for this detailed report. Unfortunately, we do not have the MPU-6050 slave so we can't reproduce.
Could you provide an example without usage of external device?

Note: I guess you have PU resistors on each I2C lines?

@yec23
Copy link
Author

yec23 commented Jul 11, 2023

Hi and thank you for your answer.

Do you expect the Wire library example "master_reader_writer" ? Tell me.
I would be surprised it does not work as it comes with the Core and was, I guess tested Ok.

I don't have external resistors. Setup proved to be fine when compiled with RC so I concluded I did not have to investigate further this possibility. Isn’t it a good enough prove that the issue is not coming from that area?

Thanks again for your help.

@fpistm
Copy link
Member

fpistm commented Jul 11, 2023

Isn’t it a good enough prove that the issue is not coming from that area?

Not necessarily as RC core could implement workaround and also probably set pins with PU. So please ensure to have PU on each I2C lines.

@yec23
Copy link
Author

yec23 commented Jul 11, 2023

Can I provide you with GPIOB->CRH: 0x4444DD44,
Mode10: 01b => Output mode, max speed 10 MHz
CNF10 : 11b => Alternate function output Open-drain
Mode11: 01b => Output mode, max speed 10 MHz
CNF11 : 11b => Alternate function output Open-drain

@fpistm
Copy link
Member

fpistm commented Jul 11, 2023

Is it for RC or this core?

@fpistm
Copy link
Member

fpistm commented Jul 12, 2023

You can add this to your sketch to enable internal PU (https://github.com/stm32duino/Arduino_Core_STM32/wiki/Custom-definitions#custom-pinmap-array):

const PinMap PinMap_I2C_SDA[] = {
  {PB_11, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_PULLUP, AFIO_NONE)},
  {NC,    NP,   0}
};

const PinMap PinMap_I2C_SCL[] = {
  {PB_10, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_PULLUP, AFIO_NONE)},
  {NC,    NP,   0}
};

@fpistm fpistm added this to To do in STM32 core based on ST HAL via automation Jul 12, 2023
@yec23
Copy link
Author

yec23 commented Jul 12, 2023

Hi, I've added the two variables declaration. Result is the same: SDA low after requestFrom call.
GPIOB->CRH: changed to 0x44449944: CNF 10 and 11 = 10b. MODE remaining 01b

@yec23
Copy link
Author

yec23 commented Jul 13, 2023

GPIO CRH provided were for the STM32 Core.
RC compilation uses GPIO CRH 0x4443FF44

  • Mode 10/11: 11b => Output mode, max speed 50 MHz
  • CNF10/11 : 11b => Alternate function output Open-drain
    STM Reference manual (RM008 9.1.11 GPIO configurations for device peripherals, Table 27. I2C) says both lines should be configured “Alternate function open drain”.

To answer “Note: I guess you have PU resistors on each I2C lines?”
I added 2K Pull-Up resistors on each I2C line. Results remain the same i.e., no STOP sequence but still hese 8 SDA HIGH before line goes down.
image

Registers are having same values
CR1: A01
CR2: 424
SR1: 240
SR2: 2

I think I have answered all your points. Tell me if can investigate others. Thank you again for your insights.

@fpistm
Copy link
Member

fpistm commented Jul 13, 2023

I have no more insight. Or maybe related to stretch feature anyway as I can not reproduce I could not help more.

/Edit:
1: 2k is maybe too low, usually we used 4.7K.
2: I've updated my comment to change STM_MODE_AF_OD to STM_MODE_AF_OD, if you can test?

@yec23
Copy link
Author

yec23 commented Jul 14, 2023

1: Put 4.7K resitors in place of 2K
2: Change code to use STM_MODE_AF_OD
Still facing the issue.

Could you clarify following point : when in Master Receiver mode, STM32F103xx RM008 describes two methods
Do you confirm the Core uses Method 2. i.e. "Interruption Mode" ? Is there a way to use Method 1 i.e. "Blocking mode" ?

@brightproject
Copy link

brightproject commented Jul 16, 2023

Just the other day I updated the core STMicroelectronics v.2.6.0, and the MPU9250 stopped working.

@fpistm
Copy link
Member

fpistm commented Jul 20, 2023

I got an MPU 6050 and test your code and see no issue.
I've also tested with https://github.com/electroniccats/mpu6050 and it works as expected.

@brightproject
Copy link

I got an MPU 6050 and test your code and see no issue.

If you have data in the fields of the magnetometer, then you have not 6500, but 9250.

@fpistm
Copy link
Member

fpistm commented Jul 20, 2023

I got an MPU 6050 and test your code and see no issue.

If you have data in the fields of the magnetometer, then you have not 6500, but 9250.

I told 6050 not 6500...

@brightproject
Copy link

I told 6050 not 6500...

I overlooked ... I didn’t think at all that there was a 6050.

@yec23
Copy link
Author

yec23 commented Jul 21, 2023

@fpistm thank you for your additional tests and feedback. Sorry for the long answer.

I performed same tests and in addition IMU_Zero.ino example from MPU6050 library. I faced the same issue with the Core. I also did the tests with a new blue pill and a new MPU-6050 (ITG-MPU).

I then decided to open the code and have a look …
I Modified i2c_master_read (twi.c) to use HAL_I2C_Master_Receive (blocking) in place of HAL_I2C_Master_Seq_Receive_IT => same issue
Had a closer look at HAL_I2C_Master_Receive and the RM08 Figure 274. "Method 1: transfer sequence diagram for master receiver. "

HAL_I2C_Master_Receive implements scenarios depending on number of variables to read

  • 1 variable: is working made no changes.
  • 2 variables: code sequence of actions is not what is described in Method1 => changed it
  • 3 variables: scenario not existing in RM08 => removed it to loop if more than 2 and not 3 variables
  • More than 3 => made no change

Long story short, I now have a HAL_I2C_Master_Receive_Method1 function that works whith my Arduino test code and IMU_Zero example also.

In addition, I performed the same tests with a compass (HMC5883) and a barometer (MS5611): both worked well with the Core ! (and the HAL_I2C_Master_Receive_Method1) …

I would then conclude my MPU-6050 (ITG-MPU) is a bit “sensitive” but still HAL_I2C_Master_Receive function code is unclear to me.

Thank you again for your help on that matter

@fpistm
Copy link
Member

fpistm commented Jul 24, 2023

@yec23
in fact the i2c_master_read is somehow blocking as we do the request to request then we poll the state with HAL_I2C_GetState.
Honestly, I don't know what do more as I can't reproduce your issue.
Are you sure you have a legacy STM32F103? There is a lot of fake now.

@yec23
Copy link
Author

yec23 commented Jul 27, 2023

"Are you sure you have a legacy STM32F103? " As I don't know how to answer that one, I can propose a photo but I guess that won't close the point of having a legacy.

image

As wrote at the beginning, all works fine with RC framework, I can reproduce it on a different "blue pill" and MPU 6050, having HAL_I2C_Master_Receive following datasheet method1 makes it work. So, it is telling me there is a possibility it is coming from the Core but as you cannot reproduce it and I have seen other sensors working Ok, it makes it weird.

For now, I propose we close on this and see if the community reopens it.

Again, a big thank you for your time.

@yec23 yec23 closed this as completed Jul 27, 2023
STM32 core based on ST HAL automation moved this from To do to Done Jul 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Development

No branches or pull requests

3 participants