1 /*****************************************************************************
2 * i2c.c: I2C C file for NXP LPC11xx/13xx Family Microprocessors
4 * Copyright(C) 2008, NXP Semiconductor
5 * Parts of this code are (C) 2010, MyVoice CAD/CAM Services
9 * 2009.12.07 ver 1.00 Preliminary version, first Release
10 * 2010.07.19 ver 1.10 Rob Jansen - MyVoice CAD/CAM Services:
11 * Major cleaning and a rewrite of some functions
12 * - adding ACK/NACK handling to the state machine
13 * - adding a return result to the I2CEngine()
15 *****************************************************************************/
18 volatile uint32_t I2CMasterState
= I2CSTATE_IDLE
;
19 volatile uint32_t I2CSlaveState
= I2CSTATE_IDLE
;
21 volatile uint8_t I2CMasterBuffer
[I2C_BUFSIZE
];
22 volatile uint8_t I2CSlaveBuffer
[I2C_BUFSIZE
];
23 volatile uint32_t I2CReadLength
;
24 volatile uint32_t I2CWriteLength
;
26 volatile uint32_t RdIndex
= 0;
27 volatile uint32_t WrIndex
= 0;
30 /*****************************************************************************
31 ** Function name: I2C_IRQHandler
33 ** Descriptions: I2C interrupt handler, deal with master mode only.
36 ** Returned value: None
38 *****************************************************************************/
39 void I2C_IRQHandler(void)
43 /* this handler deals with master read and master write only */
44 StatValue
= I2C_I2CSTAT
;
49 * A START condition has been transmitted.
50 * We now send the slave address and initialize
52 * (we always start with a write after START+SLA)
55 I2C_I2CDAT
= I2CMasterBuffer
[WrIndex
++];
56 I2C_I2CCONCLR
= (I2CONCLR_SIC
| I2CONCLR_STAC
);
57 I2CMasterState
= I2CSTATE_PENDING
;
62 * A repeated START condition has been transmitted.
63 * Now a second, read, transaction follows so we
64 * initialize the read buffer.
67 /* Send SLA with R bit set, */
68 I2C_I2CDAT
= I2CMasterBuffer
[WrIndex
++];
69 I2C_I2CCONCLR
= (I2CONCLR_SIC
| I2CONCLR_STAC
);
74 * SLA+W has been transmitted; ACK has been received.
75 * We now start writing bytes.
77 I2C_I2CDAT
= I2CMasterBuffer
[WrIndex
++];
78 I2C_I2CCONCLR
= I2CONCLR_SIC
;
83 * SLA+W has been transmitted; NOT ACK has been received.
84 * Send a stop condition to terminate the transaction
85 * and signal I2CEngine the transaction is aborted.
87 I2C_I2CCONSET
= I2CONSET_STO
;
88 I2C_I2CCONCLR
= I2CONCLR_SIC
;
89 I2CMasterState
= I2CSTATE_SLA_NACK
;
94 * Data in I2DAT has been transmitted; ACK has been received.
95 * Continue sending more bytes as long as there are bytes to send
96 * and after this check if a read transaction should follow.
98 if ( WrIndex
< I2CWriteLength
)
100 /* Keep writing as long as bytes avail */
101 I2C_I2CDAT
= I2CMasterBuffer
[WrIndex
++];
105 if ( I2CReadLength
!= 0 )
107 /* Send a Repeated START to initialize a read transaction */
108 /* (handled in state 0x10) */
109 I2C_I2CCONSET
= I2CONSET_STA
; /* Set Repeated-start flag */
113 I2CMasterState
= I2CSTATE_ACK
;
114 I2C_I2CCONSET
= I2CONSET_STO
; /* Set Stop flag */
117 I2C_I2CCONCLR
= I2CONCLR_SIC
;
122 * Data byte in I2DAT has been transmitted; NOT ACK has been received
123 * Send a STOP condition to terminate the transaction and inform the
124 * I2CEngine that the transaction failed.
126 I2C_I2CCONSET
= I2CONSET_STO
;
127 I2C_I2CCONCLR
= I2CONCLR_SIC
;
128 I2CMasterState
= I2CSTATE_NACK
;
133 * Arbitration loss in SLA+R/W or Data bytes.
134 * This is a fatal condition, the transaction did not complete due
135 * to external reasons (e.g. hardware system failure).
136 * Inform the I2CEngine of this and cancel the transaction
137 * (this is automatically done by the I2C hardware)
139 I2CMasterState
= I2CSTATE_ARB_LOSS
;
140 I2C_I2CCONCLR
= I2CONCLR_SIC
;
145 * SLA+R has been transmitted; ACK has been received.
147 * Since a NOT ACK is sent after reading the last byte,
148 * we need to prepare a NOT ACK in case we only read 1 byte.
150 if ( I2CReadLength
== 1 )
152 /* last (and only) byte: send a NACK after data is received */
153 I2C_I2CCONCLR
= I2CONCLR_AAC
;
157 /* more bytes to follow: send an ACK after data is received */
158 I2C_I2CCONSET
= I2CONSET_AA
;
160 I2C_I2CCONCLR
= I2CONCLR_SIC
;
165 * SLA+R has been transmitted; NOT ACK has been received.
166 * Send a stop condition to terminate the transaction
167 * and signal I2CEngine the transaction is aborted.
169 I2C_I2CCONSET
= I2CONSET_STO
;
170 I2C_I2CCONCLR
= I2CONCLR_SIC
;
171 I2CMasterState
= I2CSTATE_SLA_NACK
;
176 * Data byte has been received; ACK has been returned.
177 * Read the byte and check for more bytes to read.
178 * Send a NOT ACK after the last byte is received
180 I2CSlaveBuffer
[RdIndex
++] = I2C_I2CDAT
;
181 if ( RdIndex
< (I2CReadLength
-1) )
183 /* lmore bytes to follow: send an ACK after data is received */
184 I2C_I2CCONSET
= I2CONSET_AA
;
188 /* last byte: send a NACK after data is received */
189 I2C_I2CCONCLR
= I2CONCLR_AAC
;
191 I2C_I2CCONCLR
= I2CONCLR_SIC
;
196 * Data byte has been received; NOT ACK has been returned.
197 * This is the last byte to read.
198 * Generate a STOP condition and flag the I2CEngine that the
199 * transaction is finished.
201 I2CSlaveBuffer
[RdIndex
++] = I2C_I2CDAT
;
202 I2CMasterState
= I2CSTATE_ACK
;
203 I2C_I2CCONSET
= I2CONSET_STO
; /* Set Stop flag */
204 I2C_I2CCONCLR
= I2CONCLR_SIC
; /* Clear SI flag */
209 I2C_I2CCONCLR
= I2CONCLR_SIC
;
215 /*****************************************************************************
216 ** Function name: I2CStart
218 ** Descriptions: Create I2C start condition, a timeout
219 ** value is set if the I2C never gets started,
220 ** and timed out. It's a fatal error.
223 ** Returned value: true or false, return false if timed out
225 *****************************************************************************/
226 static uint32_t I2CStart( void )
228 uint32_t timeout
= 0;
230 /*--- Issue a start condition ---*/
231 I2C_I2CCONSET
= I2CONSET_STA
; /* Set Start flag */
233 while((I2CMasterState
!= I2CSTATE_PENDING
) && (timeout
< MAX_TIMEOUT
))
238 return (timeout
< MAX_TIMEOUT
);
241 /*****************************************************************************
242 ** Function name: I2CStop
244 ** Descriptions: Set the I2C stop condition
247 ** Returned value: true or never return
249 *****************************************************************************/
250 static uint32_t I2CStop( void )
252 uint32_t timeout
= 0;
254 I2C_I2CCONSET
= I2CONSET_STO
; /* Set Stop flag */
255 I2C_I2CCONCLR
= I2CONCLR_SIC
; /* Clear SI flag */
257 /*--- Wait for STOP detected ---*/
258 while((I2C_I2CCONSET
& I2CONSET_STO
) && (timeout
< MAX_TIMEOUT
))
262 return (timeout
>= MAX_TIMEOUT
);
265 /*****************************************************************************
266 ** Function name: I2CInit
268 ** Descriptions: Initialize I2C controller
270 ** parameters: I2c mode is either MASTER or SLAVE
271 ** Returned value: true or false, return false if the I2C
272 ** interrupt handler was not installed correctly
274 *****************************************************************************/
275 uint32_t i2cInit( uint32_t I2cMode
)
277 SCB_PRESETCTRL
|= (0x1<<1);
280 SCB_SYSAHBCLKCTRL
|= (SCB_SYSAHBCLKCTRL_I2C
);
282 // Configure pin 0.4 for SCL
283 IOCON_PIO0_4
&= ~(IOCON_PIO0_4_FUNC_MASK
| IOCON_PIO0_4_I2CMODE_MASK
);
284 IOCON_PIO0_4
|= (IOCON_PIO0_4_FUNC_I2CSCL
);
286 // Configure pin 0.5 for SDA
287 IOCON_PIO0_5
&= ~(IOCON_PIO0_5_FUNC_MASK
| IOCON_PIO0_5_I2CMODE_MASK
);
288 IOCON_PIO0_5
|= IOCON_PIO0_5_FUNC_I2CSDA
;
291 I2C_I2CCONCLR
= I2C_I2CCONCLR_AAC
|
296 // See p.128 for appropriate values for SCLL and SCLH
297 #if I2C_FAST_MODE_PLUS
298 IOCON_PIO0_4
|= (IOCON_PIO0_4_I2CMODE_FASTPLUSI2C
);
299 IOCON_PIO0_5
|= (IOCON_PIO0_5_I2CMODE_FASTPLUSI2C
);
300 I2C_I2CSCLL
= I2C_SCLL_HS_SCLL
;
301 I2C_I2CSCLH
= I2C_SCLH_HS_SCLH
;
303 I2C_I2CSCLL
= I2SCLL_SCLL
;
304 I2C_I2CSCLH
= I2SCLH_SCLH
;
307 if ( I2cMode
== I2CSLAVE
)
309 I2C_I2CADR0
= SLAVE_ADDR
;
312 /* Enable the I2C Interrupt */
313 NVIC_EnableIRQ(I2C_IRQn
);
314 I2C_I2CCONSET
= I2C_I2CCONSET_I2EN
;
319 /*****************************************************************************
320 ** Function name: I2CEngine
322 ** Descriptions: The routine to complete a I2C transaction
323 ** from start to stop. All the intermitten
324 ** steps are handled in the interrupt handler.
325 ** Before this routine is called, the read
326 ** length, write length and I2C master buffer
327 ** need to be filled.
330 ** Returned value: Any of the I2CSTATE_... values. See i2c.h
332 *****************************************************************************/
333 uint32_t i2cEngine( void )
335 I2CMasterState
= I2CSTATE_IDLE
;
338 if ( I2CStart() != TRUE
)
344 /* wait until the state is a terminal state */
345 while (I2CMasterState
< 0x100);
347 return ( I2CMasterState
);
350 /*****************************************************************************
351 ** Function name: i2cSendGeneralCall
353 ** Descriptions: Sends a request to the general call address (0x00)
354 ** which should detect if there are any devices on the
355 ** i2c bus. For more information see:
356 ** http://www.i2c-bus.org/addressing/general-call-address/
359 ** Returned value: Any of the I2CSTATE_... values. See i2c.h
361 *****************************************************************************/
362 uint32_t i2cSendGeneralCall(void)
366 // Clear write buffers
368 for ( i
= 0; i
< I2C_BUFSIZE
; i
++ )
370 I2CMasterBuffer
[i
] = 0x00;
373 // Send the specified bytes
376 I2CMasterBuffer
[0] = I2C_GENERALCALL
;
377 i2cState
= i2cEngine();
382 /******************************************************************************
384 ******************************************************************************/