9 years, 3 months ago.

I2C FeRAM doesn't work as I expected.

I used following combinations:

  • STM32F103RB
  • _24LCXXX library (a basic wrapper for i2c memory, so I use FM24LC16B as replacement)
  • mbed I2C (PB_7, PB_6)

The code works sometime, I can read and write successfully to store information like password....but refused to work after several times. That's odd. I am trying to slow down the bus freq and use a scope to check the hardware.

Anyway I have to find the root cause from very low level driver.

In i2c_api.h

  • int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
  • int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)

In i2c.h

  • int read(int address, char *data, int length, bool repeated = false);
  • int write(int address, const char *data, int length, bool repeated = false);

@param repeated Repeated start, true - do not send stop at end

In i2c_api.c, int stop means sending out a STOP condition on I2C, while in i2c.h, the last param of repeated claims true is NO STOP condition.

I want to know where I can verify its implementation, it seems repeated is opposite to stop.

According to specification of FM24LC16B, I have to use following operations on this part.

Single-Byte Write

S + SLV(W) + Word Address + Data Byte + P

Multi-Byte Write used in most cases

S + SLV(W) + Word Address + Data 1 + Data 2 + P

Current-Address Read

S + SLV(R) + Data + P (No Ack from master)

Sequential Read

S + SLV(R) + Data1 + Data 2 + P (with Ack from master),

therefore, master sends ack, then read on, otherwise master sends STOP

Random Read used in most cases

S + SLV(W) + Word Address + S(repeated) + SLV(R) + Data 1 + Data 2 + P

that is the only place demands repeated start to clock in word address register. the following is as same as sequential read

Updates

I used a logic probe to sense the I2C bus with massive read/write operations. In most cases, it works fine. In very rare cases, the I2C bus corrupts. Unfortunately, it is difficult to upload image from China to mbed.

When I2C bus corrupts. The frequency of SCL is not stable, looks identical to SDA. And finally both buses are pulled low by (I guess by MCU?)

How to reset I2C logic in mbed ? Including release I2C bus lines to high level.

1 Answer

9 years, 3 months ago.

You can look at mbed-src files for the source code, but the repeated flag is inverted before given to the C hardware driver. That really isn't bugged (otherwise many more would have problems with it).

Accepted Answer

Hi, Erik

Finally I found I am using FM24CL64, instead of FM24CL16B. So I turned to the original starting point. And add massive write and read of FM24CL16B with specified patterns.

I have used a simple logic probe to sense I2C data.

In most cases, the read/write of FM24CL64 works well. However, in some cases, SDA / SCL communication corrupts,

First, SCL is not fixed on 100KHz anymore like normal operation. The SCL looks as same as SDA, and at last, SDA and SCL stops at low level. Once it happens, I have to process a power cycle to reset I2C bus.

I have updated my question for uploading my images.

I can sense it by reading the return int which indicated bus error. But how can I reset the whole I2C bus logic?

I want to know

posted by Kai Liu 26 Aug 2015

The mbed lib sadly (still) has no built-in method to reset the I2C bus. You can make it yourself by switching to GPIO and toggling the clock until the SDA is high again, and then switching back to I2C.

posted by Erik - 26 Aug 2015

mbed initialized every objects before running into main(), how can I define SDA/SCL as open drain GPIO before define them as I2C in user code?

posted by Kai Liu 23 Sep 2015

You can use the pin_mode function, but that also runs in user code. They will never be open drain until some user code runs (unless you got dedicated open drain pins). Why would it matter? By default they are inputs anyway.

posted by Erik - 23 Sep 2015