cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with ST I2C sample code?

edware
Associate III
Posted on January 09, 2008 at 23:10

Problem with ST I2C sample code?

6 REPLIES 6
edware
Associate III
Posted on May 17, 2011 at 12:20

Thanks for your feedback stone-32,

However, my code is already modified to code to allow access to my peripheral, and I do get results when single stepping - it just locks up (in a while loop) when running full speed. I will implement error handling later to cater for this, but at the moment I can't work out why it's not working.

It seems to me the coding method used in example 5 is poor - as some of the bits in I2C2 SR1 and SR2 are cleared simply by reading SR1 followed by reading SR2 (which is what the while() loop is doing).

The code relies on the assumption that the tested bits will change state at the same time. In the case of my problem, it would appear I am losing the value of the ADDR bit in I2C2SR1 - which may be a result of the continuous reading of SR1 and SR2. It is a difficult problem to resolve.

Is there any mechanism which could cause the Systick interrupt to cause the sort of problem I am seeing?

Regards

Ed

edware
Associate III
Posted on May 17, 2011 at 12:20

Hello,

I'm assembling an application using IAR Kickstart/ Jlink, which uses the STM32-SK I2C for external comms. I have based some of the code on example5 of the ST library code, and am seeing unusual behaviour -i.e. code occasionally gets stuck at the while() statements while running - however in single step mode the code works fine (I am not viewing the regiser window). I have tried slowing the I2C speed down without success..

Can anyone suggest why I am seeing this behaviour? It's getting really frustrating! :o

The offending code is below:

Code:

void I2C_EE_ByteWrite(u8* pBuffer, u8 WriteAddr) <BR>{ <BR> /* Send STRAT condition */ <BR> I2C_GenerateSTART(I2C2, ENABLE); <BR> <BR> /* Test on EV5 and clear it */ <BR> while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)); <BR> <BR> /* Send EEPROM address for write */ <BR> I2C_Send7bitAddress(I2C2, EEPROM_ADDRESS, I2C_Direction_Transmitter); <BR> <BR> /* Test on EV6 and clear it */ <BR> while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); <BR> <BR> /* Send the EEPROM's internal address to write to */ <BR> I2C_SendData(I2C2, WriteAddr); <BR> <BR> /* Test on EV8 and clear it */ <BR> while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); <BR> <BR> /* Send the byte to be written */ <BR> I2C_SendData(I2C2, *pBuffer); <BR> <BR> /* Test on EV8 and clear it */ <BR> while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); <BR> <BR> /* Send STOP condition */ <BR> I2C_GenerateSTOP(I2C2, ENABLE); <BR>}

Regards

Ed

[ This message was edited by: edware on 20-12-2007 14:10 ]

16-32micros
Associate III
Posted on May 17, 2011 at 12:20

Hi edware,

The example 5 was designed to run on STMicroelectronics STM32 board and

provides a basic example of how to use the I2C software library

and an associate I2C EEPROM driver to communicate with an M24C08 EEPROM.

That means the ''void I2C_EE_ByteWrite'' routine is configured to run following the specification of the M24C08 EEPROM mounted on that board and you should tailor it to your specific hardware or I2C external devices. 🙂

Regards, stone-32

viktor3
Associate II
Posted on May 17, 2011 at 12:20

I got similar results. I reduce the optimizer level and now is working. Don´t ask me why or how

edware
Associate III
Posted on May 17, 2011 at 12:20

As a foolw up, I have performed more testing on the I2C and found a problem with the I2C2->SR2->BUSY flag not being reset properly.

To reset the I2C2 peripheral I am using the ST library function

I2C_DeInit(I2C2);

Occasionally when my I2C locks up (when the I2C registers are set as in the attachment), the I2C_DeInit() function fails to reset the BUSY flag.

The solution is to call the DeInit() function twice in succession - this works reliably to reset the BUSY flag.

edware
Associate III
Posted on May 17, 2011 at 12:20

It appears the BUSY flag in I2C-SR2 was not reset due to the external device not being released.

The solution?

Issue a STOP command on the I2C, and then DeInit()

- only one instance of DeInit() is required.