10 // Default timeout, in milliseconds for generic read/write
12 #define I2C_DEFAULT_TIMEOUT 100
17 static volatile int i2cBusInUse;
19 static U8 *i2cDataBuffer;
20 static int i2cDataLenWrite;
21 static int i2cDataLenRead;
22 static int i2cTimeout = I2C_DEFAULT_TIMEOUT;
23 static U8 *i2cDataPtr;
24 static U8 i2cTransactions [64];
25 static int i2cTransactionsIndex;
30 #define i2cDebug(x) do { if (i2cTransactionsIndex < (int) sizeof (i2cTransactions)) i2cTransactions [i2cTransactionsIndex++] = x; } while (0)
32 static void i2cISR (void) __attribute__ ((interrupt ("IRQ")));
33 static void i2cISR (void)
35 i2cErrno = (I2C0_STAT & I2C_STAT_STATMASK);
41 // Transmit conditions
43 case I2CERR_BUSERRORx : // 0x00
45 I2C0_CONSET = I2C_CONSET_STO | I2C_CONSET_AA;
50 case I2CERR_STARTTX : // 0x08
52 i2cDebug (i2cAddress);
53 I2C0_DAT = i2cAddress;
57 case I2CERR_REPEATEDSTARTTX : // 0x10
59 i2cDebug (i2cAddress);
60 I2C0_DAT = i2cAddress;
64 case I2CERR_SLAWTX_ACKRX : // 0x18
66 i2cDebug (*i2cDataPtr);
67 I2C0_DAT = *i2cDataPtr++;
68 I2C0_CONCLR = I2C_CONCLR_STAC;
72 case I2CERR_SLAWTX_NACKRX : // 0x20
74 I2C0_CONSET = I2C_CONSET_STO;
79 case I2CERR_DATTX_ACKRX : // 0x28
81 if (--i2cDataLenWrite)
83 i2cDebug (*i2cDataPtr);
84 I2C0_DAT = *i2cDataPtr++;
85 I2C0_CONCLR = I2C_CONCLR_STAC;
92 I2C0_CONCLR = I2C_CONCLR_STAC;
93 I2C0_CONSET = I2C_CONSET_STO;
100 i2cDataPtr = i2cDataBuffer;
101 I2C0_CONSET = I2C_CONSET_STA;
107 case I2CERR_DATTX_NACKRX : // 0x30
109 I2C0_CONCLR = I2C_CONCLR_STAC;
110 I2C0_CONSET = I2C_CONSET_STO;
115 case I2CERR_ARBLOST : // 0x38
117 I2C0_CONSET = I2C_CONSET_STA;
122 // Receive byte conditions
124 case I2CERR_SLARTX_ACKRX : // 0x40
126 I2C0_CONCLR = I2C_CONCLR_STAC;
127 I2C0_CONSET = I2C_CONSET_AA;
131 case I2CERR_SLARTX_NACKRX : // 0x48
133 I2C0_CONCLR = I2C_CONCLR_STAC;
134 I2C0_CONSET = I2C_CONSET_STO;
139 case I2CERR_DATRX_ACKTX : // 0x50
141 *i2cDataPtr++ = I2C0_DAT;
142 i2cDebug (*(i2cDataPtr - 1));
144 if (--i2cDataLenRead)
146 I2C0_CONCLR = I2C_CONCLR_STAC;
147 I2C0_CONSET = I2C_CONSET_AA;
151 I2C0_CONCLR = I2C_CONCLR_STAC | I2C_CONCLR_AAC;
157 case I2CERR_DATRX_NACKTX : // 0x58
159 // *i2cDataPtr = I2C0_DAT;
160 // i2cDebug (*i2cDataPtr);
161 I2C0_CONCLR = I2C_CONCLR_STAC;
162 I2C0_CONSET = I2C_CONSET_STO;
172 I2C0_CONCLR = I2C_CONCLR_I2ENC;
178 I2C0_CONCLR = I2C_CONSET_SI;
189 SCB_PCONP |= SCB_PCONP_PCI2C0;
191 PCB_PINSEL0 = (PCB_PINSEL0 & ~(PCB_PINSEL0_P02_MASK | PCB_PINSEL0_P03_MASK)) | (PCB_PINSEL0_P02_SCL0 | PCB_PINSEL0_P03_SDA0);
193 I2C0_CONCLR = I2C_CONCLR_MASK;
194 I2C0_CONSET = I2C_CONSET_I2EN;
199 // Initialize the interrupt vector
201 VIC_IntSelect &= ~VIC_IntSelect_I2C0;
202 VIC_VectCntl7 = VIC_VectCntl_ENABLE | VIC_Channel_I2C0;
203 VIC_VectAddr7 = (int) i2cISR;
204 VIC_IntEnable = VIC_IntEnable_I2C0;
210 static int i2cTransferBytes (U8 address, U8 *buffer, int bufferLenWrite, int bufferLenRead)
213 // Determine if our first operation will be a write or read. If both, the
214 // write always occurs first.
218 else if (bufferLenRead)
222 i2cErrno = I2CERR_OTHER;
227 // Wait until last I2C operation has finished.
229 if (i2cBusInUse && i2cWaitComplete (i2cTimeout))
231 i2cErrno = I2CERR_TIMEOUT;
236 // Mark bus as in use, save the address, buffer and length
239 i2cAddress = address;
240 i2cDataBuffer = buffer;
241 i2cDataLenWrite = bufferLenWrite;
242 i2cDataLenRead = bufferLenRead;
245 i2cTransactionsIndex = 0; // ###
247 I2C0_CONCLR = I2C_CONCLR_MASK;
248 I2C0_CONSET = I2C_CONSET_I2EN;
249 I2C0_CONSET = I2C_CONSET_STA;
257 int i2cWaitComplete (int milliseconds)
263 if (milliseconds < 10)
266 for (theFuture = times (NULL) + (milliseconds / 10); i2cBusInUse; )
268 if (times (NULL) > theFuture)
270 I2C0_CONCLR = I2C_CONCLR_I2ENC;
271 i2cErrno = I2CERR_TIMEOUTWC;
283 static int i2cWriteBufferEx (U8 address, U8 *buffer, U32 bufferLength, int milliseconds)
285 if (i2cTransferBytes (address, buffer, bufferLength, 0))
288 return i2cWaitComplete (milliseconds);
291 static int i2cReadBufferEx (U8 address, U8 *buffer, U32 bufferLength, int milliseconds)
293 if (i2cTransferBytes (address, buffer, 0, bufferLength))
296 return i2cWaitComplete (milliseconds);
299 static int i2cWriteReadBufferEx (U8 address, U8 *buffer, U32 putLength, U32 getLength, int milliseconds)
301 if (i2cTransferBytes (address, buffer, putLength, getLength))
304 return i2cWaitComplete (milliseconds);
308 // DANGER, WILL ROBINSON! The callers buffer must persist until we're done
310 int i2cWriteBuffer (U8 address, U8 *buffer, U32 bufferLength)
312 return i2cWriteBufferEx (address, buffer, bufferLength, i2cTimeout);
315 int i2cReadBuffer (U8 address, U8 *buffer, U32 bufferLength)
317 return i2cReadBufferEx (address, buffer, bufferLength, i2cTimeout);
320 int i2cWriteReadBuffer (U8 address, U8 *buffer, U32 putLength, U32 getLength)
322 return i2cWriteReadBufferEx (address, buffer, putLength, getLength, i2cTimeout);
325 void i2cSetTimeout (int timeoutInMilliseconds)
327 if (timeoutInMilliseconds < 10)
328 timeoutInMilliseconds = 10;
330 i2cTimeout = timeoutInMilliseconds;
337 for (i = 0; i < i2cTransactionsIndex; i++)
338 printf ("0x%02x ", i2cTransactions [i]);