2016-02-27 01:53 AM
Hello I am using STM32F030CC to communicate with BQ3060 fuel gauge through SMBus.
Everything is working kinda fine, but I am little worried about my repeated start condition. I know reading 2 bytes from register should look like this: START ADRESSwrite ACK REGISTER ACK START ADRESSread ACK DATA ACK DATA NACK But in my case there is a STOP before the second START. I still get the data but won't this make any trouble in future? This is my routine for reading ( I have tried autoend mode and soft end mode too, no results)while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY))
{
asm('''');
}
I2C_TransferHandling(I2C1, 0x16, 1, I2C_AutoEnd_Mode, I2C_Generate_Start_Write);
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY))
{
asm('''');
}
I2C_SendData(I2C1, 0x8);
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY))
{
asm('''');
}
I2C_TransferHandling(I2C1, 0x16, 1, I2C_AutoEnd_Mode, I2C_Generate_Start_Read);
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE) == 0)
{
asm('''');
}
temp_A = I2C_ReceiveData(I2C1);
This is how it looks in Digital logic analyzer
#repeated-start #read-i2c
2016-02-27 07:13 AM
It's rather difficult to offer advice not knowing what these functions do, or where they come from. Are these from a library? Is the STOP condition perhaps a result of the ''
I2C_AutoEnd_Mode''
argument being passed?
Also, the {asm(''''); }
thing is quite unnecessary.
''while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));''
will do just fine, or for the pedants out there ''
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)){};''
2016-02-27 08:42 AM
I am not aware of any I2C slave that would be upset by a stop - start sequence rather than a repeated start.
The primary reason for having a repeated start is to be able to switch between writing and reading without releasing the bus because otherwise if you have multiple masters on the bus then another of the masters might get control of the bus. If you want to read a particular location/register in a peripheral, you'd set the location with an I2C write, then want to do an I2C read. But if another I2C master got control of the bus before you did the read, this other master could write to the peripheral and change the location - and you wouldn't realise that you'd read the wrong location!Very few systems have multi-master I2C buses. So it is generally not a problem if a controller does not do repeated-start. I suspect that many controllers that claim to do I2C* do not issue repeated-start correctly.When I looked into I2C on stm32f407, I found I could issue repeated-start correctly, but I did not get an interrupt to tell me the repeated-start had completed; I had to poll the I2C peripheral to check that it was ready for the address write. But this was writing directly to the I2C peripheral - not using the ST library.*The exception, I assume, being NXP (formerly Philips) as they invented I2C.Hope this helps,Danish2016-02-27 01:49 PM
This is the library http://www.cs.indiana.edu/~bhimebau/f3lib/html/group__I2C.html#_details
Without autoend ther is SoftEnd mode - after data is sent clock is then held down until it is detected as timeout (25ms in SMBus), and then it generates STOP condition anyways. I don't remember what exactly happened when I used reload mode, but it was generating STOP anyway.Thanks for the advice. I use theseasm('''');
because I read that for example if I wanted to make loop that does nothing it might be optimized. I don't really know how it works in STM32 but here was the thread about it http://stackoverflow.com/questions/7083482/how-to-prevent-gcc-from-optimizing-out-a-busy-wait-loop2016-02-27 01:53 PM
Great explanation, thanks! In my case it is only 1 master and 1 slave, so I guess I'm ok with this and wont try to change the code.
2016-08-31 08:00 AM
Hello
I have exactly the same problem. But I do care of the weird STOP condition. Bcause when I am using the HW PEC engine PEC is calculation form START to STOP. IF there is a STOP condition after the write command PEC value is not correctly calculated. The SMBUS Read command is defined as Addr/Write, Register, Addr/Read, Data,Data, PEC. So the PEC should be calulated with all the 5 byte. Does anybody have a hint why the Stop condition is generated? Timeout cant be because the stop condition is just generated before restart condition after less than 1 ms.