cancel
Showing results for 
Search instead for 
Did you mean: 

I2C HAL_BUSY NUCLEO-FR103RB Master

xenon
Associate II

NUCLEO STM32 I2C

Hello, I'm trying to make a master NUCLEO-FR103RB send data to a slave device using fast mode (400 kHz). Slave to master is not essential at the moment. As slave I am using the Total Phase AARDVARK in slave mode simulating a LED driver which is going to be implemented later on.

  • I2C frequency = 400 kHz
  • 0x28 Slave address
  • VCC = 5V
  • RP = 3.9 kΩ (Not sure if optimal)

 

uint8_t TX_Buffer[] = "Hello Aardvark"; // Data to send
uint16_t I2C_ADDRESS = 0x28; // Aardvark I2C address (7-bit)
HAL_I2C_IsDeviceReady(&hi2c1, (uint16_t) (I2C_ADDRESS << 1), 3, HAL_MAX_DELAY);
HAL_I2C_Master_Transmit_IT(&hi2c1, I2C_ADDRESS, TX_Buffer, sizeof(TX_Buffer));
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 400000;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;

 

The only issue is that whenever I try communicating with it the function returns HAL_BUSY every time (using both IT and normal modes).
I know there's already a lot of posts talking about the issue but I don't seem to be able to solve it. I am using a pullup resistor for each line and when "idling" both are logic level HIGH which it's correct if I'm not mistaken. When trying to send data from the MCU my oscilloscope doesn't pick up any signal. I connected the peripheriial to the morpho headers and of course in the code is I2C1.image_2024-09-19_131011655.png

 

I2C.drawio (1).png

 If I put the AARDVARK in master mode and try sending data from it I can clearly see the two lines on the oscilloscope display.

Does somebody happen to know any possible solution? It's also my first time using AARDVARK, but any random peripherial will do if that's the case. The goal of this is to get me started with I2C so I can build an application for when the LP5024EVM arrives.

Thank you very much in advance for any suggestion,

1 ACCEPTED SOLUTION

Accepted Solutions
xenon
Associate II

UPDATE:

I can now successefully enstablish a connection and send master-to-slave data. I simply rewrote the code in a cleaner way and tried 100 kHz before stepping up to 400 kHz. Nothing really changed except that now the address's bit is shifted when declared instead of doing it in the function inputs.
This the address initialization and buffer part:

static const uint8_t I2C_ADDRESS = 0x28 << 1;
uint8_t tx_buffer[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};

Alive check function (sends 0x00 in the buffer):

HAL_I2C_IsDeviceReady(&hi2c1, I2C_ADDRESS, 2, HAL_MAX_DELAY);

Blocking function:

HAL_I2C_Master_Transmit(&hi2c1, I2C_ADDRESS, tx_buffer, sizeof(tx_buffer), HAL_MAX_DELAY);

Non-blocking (interrupt driven) function:

HAL_I2C_Master_Transmit_IT(&hi2c1, I2C_ADDRESS, tx_buffer, sizeof(tx_buffer));

Both of them have the same result:image_2024-09-20_101845595.png

My next step will be slave-to-master communication. I can now mark this issue as solved. Thanks to @TDK  and @Peter BENSCH for taking your time to answer me. I also didn't know I couldn't apply 5V to GPIO pins when the VDD was unpowered.

View solution in original post

6 REPLIES 6
TDK
Guru

What exactly is returning HAL_BUSY?

If HAL_I2C_IsDeviceReady returns HAL_BUSY, it means the BUSY bit is set, which means SDA or SCL is low. This indicates a hardware issue of some kind.

TDK_0-1726750195352.png

 

If you feel a post has answered your question, please click "Accept as Solution".
Peter BENSCH
ST Employee

@xenon You also cannot connect a 5V I2C device directly to the STM32 without a level shifter.

[corrected, see justification with reference to AN4899 below]

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
xenon
Associate II

Both the transmit and IsDeviceReady returned busy, however the both the SDA and SCL were high.
In the end I was able to send master to slave data with the blocking function. I moved the bit shifting phase at the declaration of the address since I also saw I was often forgetting it. If tomorrow I'll be able to implement the interrupts successefully I'll mark this thread as solved and make an update post showing what I did.
Thank you very much for your reply though

Why not? All GPIO pins are designed to be 5V tolerant. I am also using the open drain configuration if that changes something.
In the end I was able to successefully send master to slave data through 5V. Withouth interrupts though. As I said in an other reply I'll post an update tomorrow explaining everything better.
Please let me know and thanks for replying

Sorry, I had confused this with another application. Yes, you can communicate with a I2C at 5V, as discussed in AN4899, section 5.3.3.

The only restriction: the 5V must not be applied when VDD of the STM32 is switched off, because this exceeds the absolute max ratings (max VDD+4.0V). This also applies to transients that can be intercepted with a TVS or Zener, as shown at the end of section 5.3.3.

Regards
/Peter

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
xenon
Associate II

UPDATE:

I can now successefully enstablish a connection and send master-to-slave data. I simply rewrote the code in a cleaner way and tried 100 kHz before stepping up to 400 kHz. Nothing really changed except that now the address's bit is shifted when declared instead of doing it in the function inputs.
This the address initialization and buffer part:

static const uint8_t I2C_ADDRESS = 0x28 << 1;
uint8_t tx_buffer[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};

Alive check function (sends 0x00 in the buffer):

HAL_I2C_IsDeviceReady(&hi2c1, I2C_ADDRESS, 2, HAL_MAX_DELAY);

Blocking function:

HAL_I2C_Master_Transmit(&hi2c1, I2C_ADDRESS, tx_buffer, sizeof(tx_buffer), HAL_MAX_DELAY);

Non-blocking (interrupt driven) function:

HAL_I2C_Master_Transmit_IT(&hi2c1, I2C_ADDRESS, tx_buffer, sizeof(tx_buffer));

Both of them have the same result:image_2024-09-20_101845595.png

My next step will be slave-to-master communication. I can now mark this issue as solved. Thanks to @TDK  and @Peter BENSCH for taking your time to answer me. I also didn't know I couldn't apply 5V to GPIO pins when the VDD was unpowered.