Electronic – How to get I2C to shut up while waiting for data in master transmit mode on LPC1114

i2cinterruptslpcnxp

I have an LPC1114(FN28) that I am writing some code for. Currently I am trying to provide an asynchronous view of the I2C interface to my code (the chip has a built-in I2C controller). The controller itself is basically a state machine, but since the I2C spec specifies no timeout or other restrictions on the SCL clock rate, I should be able to delay sending (it doesn't have to be perfectly synchronous) as long as the controller controls SCL correctly when data is being sent, and holds it low when no data is being sent.

The idea is to be able to buffer data to be sent on the I2C bus. A few libraries I see around deal with this by just buffering the whole thing and bitbanging it all at once, which is okay most of the time since you generally don't send lots of data over I2C, but I want to do it properly.

I've set up the base code and the problem I am having when transmitting data is that whenever the controller enters the "transmit data to slave" mode, it triggers an interrupt requiring me to fill in a byte of data to send (or send a STOP signal). The problem is if I do nothing, it immediately issues the same interrupt, so my main code can't even get the chance to execute! What I want is the ability to tell the controller "I have no bytes to send right now, so don't issue another interrupt until I tell you to from my main code"!

I've rigged something up that works by (ab?)using the NVIC to disable the I2C interrupt when I am waiting for data, and re-enabling it when I am ready to send on the I2C interface, but this seems very unorthodox and I don't know if it is actually reliable or even correct especially if bad stuff should happen to the bus in the meantime (bus error, etc…)

Here is the manual for the chip, the docs for the I2C controller are at page 239. I thought I could use the SI control bit to tell it to not issue an interrupt until I clear it again but apparently that's not what it's for.

Does anyone have experience with this or similar I2C controllers and know how I can achieve what I am looking for? Clearly it must be possible, since a protocol where you need to have all the data ready up front every time doesn't seem viable to me.

Best Answer

Disabling the interrupt when you have no data to send is exactly the correct approach to take with a hardware I2C master controller.

When the data is available, re-enable the interrupt and you'll immediately take it, which will transfer the byte to the controller.