lpcware

LPC4350 LPCOpen v2.12 gets stuck in I2C Master Communications

Discussion created by lpcware Employee on Jun 15, 2016
Content originally posted in LPCWare by gregd on Mon Jun 22 13:26:51 MST 2015
I have some concerns that the i2c driver in LPCOpen for the LPC4350 has some areas where lockups can occur.  I am using v2.12 but I believe the i2c driver is the same in newer versions.  I have seen these lockup conditions several times during my development but have kind of attributed them to the extenuating circumstances of debugging.  Over the weekend I experienced a problem with a LPC4350 based board which monitors temperature and humidity inside our environmental chamber.  We have been using this board for months with no prior problems.  The board is connected to an i2c temperature/humidity sensor using a 10 position ribbon cable, approximately 3 feet long.  The board is located outside the environmental test chamber.  The i2c ribbon cable runs through a hole in the side of the environmental chamber to the i2c humidity/temperature sensor which is inside the chamber.  As I mentioned before, we have been using this board for many months to log the chamber temperature and humidity every second without any problems.  This same board is used in our electronic gas flow computer products which we strive to maintain very high reliability.  I would like to avoid any of these lockup conditions the actual products that we ship to our customers.

Over the weekend, we were testing another product in the chamber - A mechanical relay was being used to generate some electrical noise to test susceptibility.  I am sure that some of the noise was being coupled onto the ribbon cable. 

When I got in to work this morning, I noticed that my temperature/humidity monitor board was locked up.  I connected a battery as a power source and carefully moved the board to my lab to evaluate the problem.  I was able to connect to the running target with IAR IDE without removing the power.   I discovered that the M0 processor was locked up in the while loop below:

void Chip_I2C_EventHandlerPolling(I2C_ID_T id, I2C_EVENT_T event)
{
                struct i2c_interface *iic = &i2c[id];
                volatile I2C_STATUS_T *stat;

                /* Only WAIT event needs to be handled */
                if (event != I2C_EVENT_WAIT) {
                                return;
                }

                stat = &iic->mXfer->status;
                /* Call the state change handler till xfer is done */
                while (*stat == I2C_STATUS_BUSY) {
                                if (Chip_I2C_IsStateChanged(id)) {
                                                Chip_I2C_MasterStateHandler(id);
                                }
                }


The SI bit in the i2c->CONSET register was never being set so Chip_I2C_IsStateChanged(id) was always returning false.  It was stuck in this loop from Friday night until Monday morning.  I also noticed that the STA and I2EN bits were the only ones that were set in the i2c->CONSET register.

I found the following link which was very helpful in describing exactly what was going on:
http://www.lpcware.com/content/forum/lpcopenlpc17xx-i2c-master-freeze

I was able to force the application to recover by setting the STO bit in the i2c->CONSET register – As the LPC4350 User Manual states in section 46.10.6.3, this is a way Force Access to the i2c bus.

Do you have any plans to improve the robustness of the i2c driver by adding this support in LPCOpen?  I have also seen where one of the slave devices can get out of sync and hold the SDA line low.  The current driver will also lock up in this case.  It would be nice to have some provisions for feeding extra clock pulses to get the slave device release the SDA line. 

Is there a list of specific areas in LPCOpen that the customer should be sure to review/modify if they need to make sure that no lockups occur?


Outcomes