chipKIT® Development Platform

Inspired by Arduino™

Non-blocking i2c (twi) library and question about i2c reset.

Created Mon, 28 Apr 2014 14:23:44 +0000 by youri


Mon, 28 Apr 2014 14:23:44 +0000

Hello, I am noticing issues with i2c while loops locking up my code execution. I was wondering if this arduino commit could be implemented into the mpide i2c library.

All that's happening is there is a time out on the (while) reads in twi.c.

+  twi_timeout_guard(1);
 +  while((TWI_READY != twi_state) && !twi_timeout_guard(0)){

Also, can anyone help me with resetting my I2c once it does lock up? I've put the timeout code into my twi library but I want to react to the time outs - just not sure how - can I use TWCR like the example?

The example calls twi_init() once the time out happens - but I can't do that since the mpide twi_init takes a bunch of parameters.



Wed, 30 Apr 2014 15:08:09 +0000

Update, setting:

I2C1CON = 0x1000

and then toggling the i2c chips on/off (via a pin added to our board) and then re-initializing them seems to have fixed the issue.

Still hoping the twi.c timeouts make it into the library.


Fri, 18 Jul 2014 13:07:31 +0000


I had problems with I2C too. I am using a board based on PIC32MX795 and I must use I2C 4 because of pin use conflicts with I2C 1.

This is not so much a problem (little changes in BoardDefs.h coming from Fubarino SD support). But it took me long to discover my first byte read (Master Read) was always in Overflow (_I2CSTAT_I2COV) and therefore wrong. I had to add: uint8_t currChar = ptwi->ixRcv.reg; // Reset Receive buffer! at the end of the switch case //Master Receiver case TW_MR_SLA: // address sent, ack received // Check if address was acked or nacked This seems coherent with diagram 24-15 (page 29) of the Microchip I2C datasheet: where step (7) is putting data in the receive buffer.

I also had to modify TWI.c/.h to take into account the varying message length that the Microchip ADC MCP3423 is providing in "One Shot" mode: if somebody needs help on this, I will happily answer!

My question is simple: does TWI authors / committers agree with the line added in case TW_MR_SLA to flush the receive buffer ?



Wed, 30 Jul 2014 11:43:28 +0000

I have similar but not the same problem with twi.c using INA219 current monitor, Uno32, uC32 boards, MPIDE 20140417-test version.

It is regularly stucks at those lines:

line 177:
// wait for read operation to complete while(TW_IDLE != TW_STATUS) { asm volatile("nop"); }

or waiting here:

line 241: // wait for write operation to complete while (wait && TW_IDLE != TW_STATUS) { asm volatile("nop"); }

Definitely waiting for the INA to do something.

My system has been running for 2 months 7/24, the problem started aroud two weeks ago. It happens sometimes once in three days, then 2-3 times in ten minutes and continues to work again.

I changed the INA219 chip, there was some change in the regularity.

After a software reset it continues to work.

The only coherence what I have discovered it happens when INA measuring the battery charging current between 7-10Amp (10 is the max in my system). And never happened during battery discharging current measurement.

The charging current is quite noisy, so this should cause the malfunction. I will try to decrease the noise entering the INA by filtering, but I have to ensure the system 100% safe on the controller side, because leaving the charging or discharging currrent on for a while destroys the battery.

I think using the PIC32 watchdog reset would be one solution (plus I have to solve to resume to the previous operation state).

I would appreciate the help to make a short explanation how could I set up the watchdog function on UNO32, uC32 boards, using MPIDE. Or if there is any other idea what solves this issue?



Wed, 30 Jul 2014 12:13:21 +0000

I have put limits on those loops: seems strange to me to consciously block a process when delays are way out the norm. Be also careful to power down your I2C chips when you reset the MCU: after a bus error, the I2C chips may need a full reset to resume normal operation.



Wed, 30 Jul 2014 13:36:36 +0000

Thanks for the answer.

I am using MPIDE as a black box (I would like...).

I am very unexperienced to create and hack libraries. I did some changes in the INA219 library, but that was inside the lib. level.

Putting a delay that still can work out.

But what would be the professional way of hacking the twi.c to make a semaphore about the stuck to communicate for the application?

Today I have a plenty of stucks. So I am able to do some debugging. I stepped over the waiting loop and back to the application code. Till now I can't get back the INA to work on the application level. I looks to be a permanent stuck.

The only way I can get back to operation that I have to make a reset in the MPLABX/ICD3 debugger, what is I suppose eqvivalent of the reset button (what is not working while in emulation). It starts from the main.c.

So it looks like it needs a hard reset when stucked. How can I make a hard reset from the application code?



Wed, 30 Jul 2014 13:56:08 +0000

I was surprised like you of the problems using I2C. I did not found any "professional" way to do the things apart from patching TWI.c , reason I tried to gather the attention of the ChipKit committers by posting here. I did not tried up to now to set a watchdog but I will have to do it sooner or later! So excuse that I cannot help you with "real experience" on this. But remember to power down your I2C chips when you reset! Christophe