cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103 - I2C failure to ack

js2
Associate II
Posted on March 08, 2017 at 00:10

Hi,

I am using an STM32F103 connected to an I2C device. I can see that the device is responding to 2 ranges of addresses, one mapped to registers, one mapped to an EEPROM address space. I can communicate with the device (writing to it and reading in memory mode) properly, but I get an ack failure when trying to read it.

I am using code straight from the cube (latest F1 version available), in poll mode. I had to modify the initialization code to go around the issue of the device being always busy (moving the initialization of the i2c clock to happen before the initialization of the i2c pins).

Regarding the read issue, I have confirmed the following with an I2C oscilloscope:

- Start is generated,

- 7 bit address is sent

- 8th is set to 1 (read request)

However the 9th clock is stuck to 1 which means the slave did not respond to the read request. In write mode the device is properly acknowledging the address on the 9th clock.

Considering the device properly responds to this address in write mode and considering the amount of issues reported with the STM32F103 i2c I am wondering if the STM32F103 is holding the 9th bit high and preventing the slave from acknowledging.

Has anybody been able to execute read requests (mast reads, not memory reads) using the cube code?

JS

12 REPLIES 12
Posted on March 08, 2017 at 00:36

The I2C pins are supposed to be set to Open-Drain mode, so the STM32 can't 'hold' the pin high then (unless silicon bug, not likely in the rather old 'F1xx). I'd bet on problem on the device side. Is the device known to answer (yes there *are* write-only I2C devices)? Is there a datasheet?

JW

Posted on March 08, 2017 at 00:40

Thanks for the reply. Yes the device is supposed to reply, this is an MLX90621, very commonly used with Arduinos etc.

The device is supposed to be readable and writable at address 0x60. I can write to this address, the device will confirm with acks. Again, the reads fail though on the first ack. The i2c receive function actually aborts before the part of the code that deals with 1, 2 and >2 data read requests.

Posted on March 08, 2017 at 00:41

It's easy to bit-bang the protocol on the master side. Try.

JW

Posted on March 08, 2017 at 00:44

That's true, though I have no doubts that the MLX90621 responds to read requests at this address.

Posted on March 08, 2017 at 01:11

the HAL wants a left-justified i2c address.  0x60 to an arduino and 0x60 to the HAL i2c driver are two different things.

try 0xC0.

Posted on March 08, 2017 at 02:07

Thanks for the reply.

I'm already sending 0xC0/0xC1. I mentioned 0x60 since this is what is specified in the datasheet of the device.

js2
Associate II
Posted on March 08, 2017 at 04:37

Thanks to all who have replied. Your answers convinced me this was not a hardware issue, but rather related to the driver or the way it was used.

I have made some progress with this issue. The way data is read out of the device is by first specifying which register is to be read. This is a 4 byte command (plus device address), followed by a 2 byte read (plus device address).

I used the polling functions provided by the cube. The transmit function ends with a stop, while the device expects a restart between the write (setting which register to read) and the read sequence.

Once I removed the stop at the end of the transmit function I got an ack from the device on the read sequence.

What I am seeing now is that I am unable to communicate with the device after the first read. The i2c peripheral seems to stay in a busy state and all calls to the i2c functions end up in a timeout.

Is there anything specific I need to do at the end of the read to get the i2c out the busy state?

S.Ma
Principal
Posted on March 08, 2017 at 08:17

Have a look at this code 

https://community.st.com/0D50X00009XkW1qSAF

 

Remember that the only reason an EEPROM would Nack reading is when it is busy programming.

Try to read 10 msec after writing. If this works, maybe the write has written more than the sub address and kicked a write sequence within the EEPROM.

Posted on March 08, 2017 at 09:52

The transmit function ends with a stop, while the device expects a restart between the write (setting which register to read) and the read sequence.

Good catch - not all I2C slaves are created equal. Given latitudes in the I2C spec, this approach appears to be legal even if dumb.

The i2c peripheral seems to stay in a busy state and all calls to the i2c functions end up in a timeout.

Has a valid STOP happened?  What's the content of I2C registers at that point?

JW