cancel
Showing results for 
Search instead for 
Did you mean: 

I2C Loopback using bare-metal code

maya16
Associate III

Hello All, I am trying to do a loopback test between 2 i2c's on the same board, using bare metal coding and interrupts, and the clk is HSI, 16MHz. How the i2c i configured as slave is failing to acknowledge the address sent by master i2c.
Here is a zip file containing the project.

6 REPLIES 6
Andrew Neil
Super User

You already have a thread on this - marked as solved:

I2C Loopback Test using STM32F429ZI

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

That was using HAL(API), this is register level programming.

So compare what happens in your bare-metal code with what happens in the (working) HAL code.

Step through both of them - see where they differ.

The chip neither knows nor cares what your code uses - it just needs to have the correct register setting, etc.

 

PS:

You seem to have switched both slave and master to bare-metal.

It would be more sensible to do just one at a time - otherwise you don't know whether the problem(s) are in the Master, or the Slave - or both!

https://community.st.com/t5/stm32-mcus-products/two-nucleo-boards-stm32f446re-and-stm32h723zg-communicate/m-p/737695/highlight/true#M264992

 


@maya16 wrote:

slave is failing to acknowledge the address sent by master i2c.


So is the master actually sending the correct address?

Or is the Slave not correctly recognising its address?

Or both?!

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

Since i am choosing the onboard i2c2 as slave, it was given i can give any address within the range of 0 to 127(decimal). So i gave 0x42 as the address. When storing in OAR1  register, i gave it as 0x42 << 1, and when passing through the data register of the master as well i gave it as 0x42 << 1. But it seems like the slave is not recognising the address being sent.

So compare all that with what happens in the working (HAL) version.

Again, change only one end at a time.

Look at what's happening on the wires - that will show you immediately if the correct Slave address is being sent...

 

I2C Addresses are notorious for confusing/misleading usage:

https://community.st.com/t5/imaging-sensors/vl53l8cx-not-working-on-nrf9151-and-getting-naks/m-p/814452/highlight/true#M5697

So looking at what actually happens on the wire is really the only way to be sure

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.
maya16
Associate III

I do not have a logic analyzer or oscilloscope to check by the signals, i can only depend on the debuggers.
Here is an updated code, i referred the HAL one, and used polling for master and interrupt for slave.
The address is for being sent on the data line is getting stored on the Data Register of master, but it's getting stuck while checking for ADDR bit. For slave, the slave address is stored correctly in the OAR1 register.