cancel
Showing results for 
Search instead for 
Did you mean: 

FMPI2C (STM32F446) working as I2C slave is not releasing the SDA line after ACK

flaretom
Associate II

Hi

The STM is configured as NOSTRETCH=1 and connected to a RL78 which acts as master. The whole configuration is used to test the SW on the RL78. The STM is emulating a number of I2C devices. The RL78 can not handle clockstreching on the used ports.

Sending from RL78 to STM works fine.

But when receiving data from the STM the correctness of the transfer depends on the transmitted data (bit7).

I have to load a new databyte into TXDR on each TXIS interrupt, as I don't know how many bytes the RL78 is requesting.

If bit7 of the databyte is 1 and the RL78 is sending a stop condition everything works fine (I2Cslave_8a.png).

If bit7 of the databyte is 0, then the RL78 can not send a stop. It seams that the STM is already putting the bit7 on the SDA which is then corrupting the stop from RL78 (I2Cslave_4a.png).

Does anybody have an idea where I did something wrong?

I attach my interrupt service routine. There is a number of lines added to debug.

Best regards, Tom

1 ACCEPTED SOLUTION

Accepted Solutions
flaretom
Associate II

Hello JW,

Thank You very much Your help. Indeed there was a problem with the RL78 SW. It never generated a NACK. After fixing this everything works fine.

Best regards, Tom

View solution in original post

6 REPLIES 6

You did nothing wrong. The master (in RL78) receiver is implemented incorrectly - according to I2C specification (UM10204 rev.6), chapter 3.1.6 Acknowledge (ACK) and Not Acknowledge (NACK):

There are five conditions that lead to the generation of a NACK:

[...]

5. A master-receiver must signal the end of the transfer to the slave transmitter.

This is reiterated in 3.1.10, not only for subsequent STOP but also repeated START condition following the end of reception (and thus the NACK from master-receiver).

In STM32, you should distinguish ACK and NACK and not output more data when NACK.

JW

PS Please change your username to a normal nick.

flaretom
Associate II

Hi JW,

Thank You for Your reply!

Yes, in the RL78 they call it a "simplified" I2C. But I'm not sure if that is the root cause of my problem (beside the fact, that I can't use clockstretching).

Anyway Start and Stop have to be generated in the RL78 by SW.

The problem is, that the RL78 is sending a valid Stop condition, but it is overwritten by data from STM (the time it is generated is reported as High-level the line XCP_Busy and btw. the interrupts in the STM by High on TogglePin0).

Maybe I'm not understanding a part in the I2C specification. According to Fig 4 in UM10204 the slave puts new data during the low phase of SCL. To signal Stop the master has to raise SCL and only then SDA.

In Fig 9. there is a short time after the 1st ACK , where both master/slave releasing the SDA --> it goes high for a short time. For a Stop the master can hold SDA low (after 2nd ACK) (this should be sensed by the slave, so it is not putting its next bit)

and then the master can generate Stop.

But in my case I don't see the SDA rise shortly after ACK in case of bit7 =0.

It seams that the slave is putting the 0 on SDA directly after the falling edge of SCL, therefore a Stop can't be send because the master can't pull SDA up.

Is there a way to delay the output of the next bit (I'm using the default timing generated by CubeMX)?

 hfmpi2c1.Instance = FMPI2C1;

 hfmpi2c1.Init.Timing = 0x00A0A3F7;

 hfmpi2c1.Init.OwnAddress1 = 0;

 hfmpi2c1.Init.AddressingMode = FMPI2C_ADDRESSINGMODE_7BIT;

 hfmpi2c1.Init.DualAddressMode = FMPI2C_DUALADDRESS_ENABLE;

 hfmpi2c1.Init.OwnAddress2 = 0;

 hfmpi2c1.Init.OwnAddress2Masks = FMPI2C_OA2_MASK07;

 hfmpi2c1.Init.GeneralCallMode = FMPI2C_GENERALCALL_DISABLE;

 hfmpi2c1.Init.NoStretchMode = FMPI2C_NOSTRETCH_ENABLE;

Best regards, Tom

I repeat, the software in RL78 is broken. It MUST respond by NACK to the last received byte, thus indicate to slave that slave ought to leave SDA up.

You can design a workaround, specially catering for the other party's bug, but then it's not I2C anymore, don't expect any I2C library/code to work in that respect and don't expect the I2C module to work correctly. You may need to resort to bit-banging. And, as it's not I2C anymore, you ought to ask the author of the RL78 software for clear guideline how to cope with the situation, otherwise it's prone to break in the future.

JW

flaretom
Associate II

H,

Maybe I'm understanding now (hopefully). During a receive-transfer the RL78 is responsible for ACK/NACK of the datahe data from slave. But if I send an ACK I'm signaling to the slave, that there will be a next byte --> STM is putting bit7 on SDA. If I would send a NACK instead, then STM knows there is no next byte transmission and won't put bit 7.

Will try this and report.

BR Tom

flaretom
Associate II

Hello JW,

Thank You very much Your help. Indeed there was a problem with the RL78 SW. It never generated a NACK. After fixing this everything works fine.

Best regards, Tom

Thanks for coming back with the result.

JW