i2c.c (13949B)
1 /***************************************************************************** 2 * i2c.c: I2C C file for NXP LPC11xx/13xx Family Microprocessors 3 * 4 * Copyright(C) 2008, NXP Semiconductor 5 * Parts of this code are (C) 2010, MyVoice CAD/CAM Services 6 * All rights reserved. 7 * 8 * History 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() 14 * 15 *****************************************************************************/ 16 #include "projectconfig.h" 17 18 #ifdef CFG_ENABLE_I2C 19 20 #include "i2c.h" 21 22 volatile uint32_t I2CMasterState = I2CSTATE_IDLE; 23 volatile uint32_t I2CSlaveState = I2CSTATE_IDLE; 24 25 volatile uint8_t i2c_write_buf[I2C_BUFSIZE]; // Master Mode 26 volatile uint8_t i2c_read_buf[I2C_BUFSIZE]; // Master Mode 27 28 volatile uint32_t i2c_read_len; 29 volatile uint32_t i2c_write_len; 30 31 volatile uint32_t I2CRdIndex; 32 volatile uint32_t I2CWrIndex; 33 34 volatile uint32_t _I2cMode; // I2CMASTER or I2CSLAVE (only master is used at present) 35 36 /***************************************************************************** 37 ** Function name: I2C_IRQHandler 38 ** 39 ** Descriptions: I2C interrupt handler, deal with master mode only. 40 ** 41 ** parameters: None 42 ** Returned value: None 43 ** 44 *****************************************************************************/ 45 void I2C_IRQHandler(void) 46 { 47 uint8_t StatValue; 48 49 /* this handler deals with master read and master write only */ 50 StatValue = LPC_I2C->STAT; 51 switch ( StatValue ) 52 { 53 case 0x08: 54 /* 55 * A START condition has been transmitted. 56 * We now send the slave address and initialize 57 * the write buffer 58 * (we always start with a write after START+SLA) 59 */ 60 I2CWrIndex = 0; 61 LPC_I2C->DAT = i2c_write_buf[I2CWrIndex++]; 62 LPC_I2C->CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC); 63 I2CMasterState = I2CSTATE_PENDING; 64 break; 65 66 case 0x10: 67 /* 68 * A repeated START condition has been transmitted. 69 * Now a second, read, transaction follows so we 70 * initialize the read buffer. 71 */ 72 I2CRdIndex = 0; 73 /* Send SLA with R bit set, */ 74 LPC_I2C->DAT = i2c_write_buf[I2CWrIndex++]; 75 LPC_I2C->CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC); 76 break; 77 78 case 0x18: 79 /* 80 * SLA+W has been transmitted; ACK has been received. 81 * We now start writing bytes. 82 */ 83 LPC_I2C->DAT = i2c_write_buf[I2CWrIndex++]; 84 LPC_I2C->CONCLR = I2CONCLR_SIC; 85 break; 86 87 case 0x20: 88 /* 89 * SLA+W has been transmitted; NOT ACK has been received. 90 * Send a stop condition to terminate the transaction 91 * and signal I2CEngine the transaction is aborted. 92 */ 93 LPC_I2C->CONSET = I2CONSET_STO; 94 LPC_I2C->CONCLR = I2CONCLR_SIC; 95 I2CMasterState = I2CSTATE_SLA_NACK; 96 break; 97 98 case 0x28: 99 /* 100 * Data in I2DAT has been transmitted; ACK has been received. 101 * Continue sending more bytes as long as there are bytes to send 102 * and after this check if a read transaction should follow. 103 */ 104 if ( I2CWrIndex < i2c_write_len ) 105 { 106 /* Keep writing as long as bytes avail */ 107 LPC_I2C->DAT = i2c_write_buf[I2CWrIndex++]; 108 } 109 else 110 { 111 if ( i2c_read_len != 0 ) 112 { 113 /* Send a Repeated START to initialize a read transaction */ 114 /* (handled in state 0x10) */ 115 LPC_I2C->CONSET = I2CONSET_STA; /* Set Repeated-start flag */ 116 } 117 else 118 { 119 I2CMasterState = I2CSTATE_ACK; 120 LPC_I2C->CONSET = I2CONSET_STO; /* Set Stop flag */ 121 } 122 } 123 LPC_I2C->CONCLR = I2CONCLR_SIC; 124 break; 125 126 case 0x30: 127 /* 128 * Data byte in I2DAT has been transmitted; NOT ACK has been received 129 * Send a STOP condition to terminate the transaction and inform the 130 * I2CEngine that the transaction failed. 131 */ 132 LPC_I2C->CONSET = I2CONSET_STO; 133 LPC_I2C->CONCLR = I2CONCLR_SIC; 134 I2CMasterState = I2CSTATE_NACK; 135 break; 136 137 case 0x38: 138 /* 139 * Arbitration loss in SLA+R/W or Data bytes. 140 * This is a fatal condition, the transaction did not complete due 141 * to external reasons (e.g. hardware system failure). 142 * Inform the I2CEngine of this and cancel the transaction 143 * (this is automatically done by the I2C hardware) 144 */ 145 I2CMasterState = I2CSTATE_ARB_LOSS; 146 LPC_I2C->CONCLR = I2CONCLR_SIC; 147 break; 148 149 case 0x40: 150 /* 151 * SLA+R has been transmitted; ACK has been received. 152 * Initialize a read. 153 * Since a NOT ACK is sent after reading the last byte, 154 * we need to prepare a NOT ACK in case we only read 1 byte. 155 */ 156 if ( i2c_read_len == 1 ) 157 { 158 /* last (and only) byte: send a NACK after data is received */ 159 LPC_I2C->CONCLR = I2CONCLR_AAC; 160 } 161 else 162 { 163 /* more bytes to follow: send an ACK after data is received */ 164 LPC_I2C->CONSET = I2CONSET_AA; 165 } 166 LPC_I2C->CONCLR = I2CONCLR_SIC; 167 break; 168 169 case 0x48: 170 /* 171 * SLA+R has been transmitted; NOT ACK has been received. 172 * Send a stop condition to terminate the transaction 173 * and signal I2CEngine the transaction is aborted. 174 */ 175 LPC_I2C->CONSET = I2CONSET_STO; 176 LPC_I2C->CONCLR = I2CONCLR_SIC; 177 I2CMasterState = I2CSTATE_SLA_NACK; 178 break; 179 180 case 0x50: 181 /* 182 * Data byte has been received; ACK has been returned. 183 * Read the byte and check for more bytes to read. 184 * Send a NOT ACK after the last byte is received 185 */ 186 i2c_read_buf[I2CRdIndex++] = LPC_I2C->DAT; 187 if ( I2CRdIndex < (i2c_read_len-1) ) 188 { 189 /* lmore bytes to follow: send an ACK after data is received */ 190 LPC_I2C->CONSET = I2CONSET_AA; 191 } 192 else 193 { 194 /* last byte: send a NACK after data is received */ 195 LPC_I2C->CONCLR = I2CONCLR_AAC; 196 } 197 LPC_I2C->CONCLR = I2CONCLR_SIC; 198 break; 199 200 case 0x58: 201 /* 202 * Data byte has been received; NOT ACK has been returned. 203 * This is the last byte to read. 204 * Generate a STOP condition and flag the I2CEngine that the 205 * transaction is finished. 206 */ 207 i2c_read_buf[I2CRdIndex++] = LPC_I2C->DAT; 208 I2CMasterState = I2CSTATE_ACK; 209 LPC_I2C->CONSET = I2CONSET_STO; /* Set Stop flag */ 210 LPC_I2C->CONCLR = I2CONCLR_SIC; /* Clear SI flag */ 211 break; 212 213 default: 214 LPC_I2C->CONCLR = I2CONCLR_SIC; 215 break; 216 } 217 return; 218 } 219 220 /***************************************************************************** 221 ** Function name: I2CStart 222 ** 223 ** Descriptions: Create I2C start condition, a timeout 224 ** value is set if the I2C never gets started, 225 ** and timed out. It's a fatal error. 226 ** 227 ** parameters: None 228 ** Returned value: true or false, return false if timed out 229 ** 230 *****************************************************************************/ 231 static uint32_t I2CStart( void ) 232 { 233 uint32_t timeout = 0; 234 235 /*--- Issue a start condition ---*/ 236 LPC_I2C->CONSET = I2CONSET_STA; /* Set Start flag */ 237 238 while((I2CMasterState != I2CSTATE_PENDING) && (timeout < MAX_TIMEOUT)) 239 { 240 timeout++; 241 } 242 243 return (timeout < MAX_TIMEOUT); 244 } 245 246 /***************************************************************************** 247 ** Function name: I2CStop 248 ** 249 ** Descriptions: Set the I2C stop condition 250 ** 251 ** parameters: None 252 ** Returned value: true or never return 253 ** 254 *****************************************************************************/ 255 static uint32_t I2CStop( void ) 256 { 257 uint32_t timeout = 0; 258 259 LPC_I2C->CONSET = I2CONSET_STO; /* Set Stop flag */ 260 LPC_I2C->CONCLR = I2CONCLR_SIC; /* Clear SI flag */ 261 262 /*--- Wait for STOP detected ---*/ 263 while((LPC_I2C->CONSET & I2CONSET_STO) && (timeout < MAX_TIMEOUT)) 264 { 265 timeout++; 266 } 267 return (timeout >= MAX_TIMEOUT); 268 } 269 270 /***************************************************************************** 271 ** Function name: I2CInit 272 ** 273 ** Descriptions: Initialize I2C controller 274 ** 275 ** parameters: I2c mode is either MASTER or SLAVE 276 ** Returned value: true or false, return false if the I2C 277 ** interrupt handler was not installed correctly 278 ** 279 *****************************************************************************/ 280 uint32_t i2cInit( uint32_t I2cMode ) 281 { 282 _I2cMode = I2cMode; 283 284 LPC_SYSCON->PRESETCTRL |= (0x1<<1); 285 286 /* Enable AHB clock to the I2C domain. */ 287 LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 5); 288 289 /* Set P0.4 to SCL and I2C mode (open drain) */ 290 LPC_IOCON->PIO0_4 &= ~0x07 | 0x300; /* Add I2C mode mask */ 291 LPC_IOCON->PIO0_4 |= 0x01; 292 293 /* Set P0.5 to SDA and I2C mode (open drain) */ 294 LPC_IOCON->PIO0_5 &= ~0x07 | 0x300; /* Add I2C mode mask */ 295 LPC_IOCON->PIO0_5 |= 0x01; 296 297 // Clear flags 298 LPC_I2C->CONCLR = I2CONCLR_AAC | 299 I2CONCLR_SIC | 300 I2CONCLR_STAC | 301 I2CONCLR_I2ENC; 302 303 #if I2C_FAST_MODE_PLUS 304 LPC_IOCON->PIO0_4 |= (0x200); /* Fast mode plus */ 305 LPC_IOCON->PIO0_5 |= (0x200); /* Fast mode plus */ 306 LPC_I2C->SCLL = I2C_SCLL_HS_SCLL; 307 LPC_I2C->SCLH = I2C_SCLH_HS_SCLH; 308 #else 309 LPC_I2C->SCLL = I2SCLL_SCLL; 310 LPC_I2C->SCLH = I2SCLH_SCLH; 311 #endif 312 313 if ( _I2cMode == I2CSLAVE ) 314 { 315 LPC_I2C->ADR0 = SLAVE_ADDR; 316 I2CSlaveState = I2C_IDLE; 317 } 318 319 /* Enable the I2C Interrupt */ 320 NVIC_EnableIRQ(I2C_IRQn); 321 if ( _I2cMode == I2CMASTER ) 322 { 323 LPC_I2C->CONSET = I2CONSET_I2EN; 324 } 325 326 return( TRUE ); 327 } 328 329 /***************************************************************************** 330 ** Function name: I2CEngine 331 ** 332 ** Descriptions: The routine to complete a I2C transaction 333 ** from start to stop. All the intermitten 334 ** steps are handled in the interrupt handler. 335 ** Before this routine is called, the read 336 ** length, write length and I2C master buffer 337 ** need to be filled. 338 ** 339 ** parameters: None 340 ** Returned value: Any of the I2CSTATE_... values. See i2c.h 341 ** 342 *****************************************************************************/ 343 uint32_t i2cEngine( void ) 344 { 345 I2CMasterState = I2CSTATE_IDLE; 346 I2CRdIndex = 0; 347 I2CWrIndex = 0; 348 if ( I2CStart() != TRUE ) 349 { 350 // I2C timed out 351 I2CStop(); 352 return ( I2CSTATE_TIMEOUT ); 353 } 354 355 /* wait until the state is a terminal state */ 356 while (I2CMasterState < 0x100); 357 358 return ( I2CMasterState ); 359 } 360 361 /***************************************************************************** 362 ** Function name: i2cCheckAddress 363 ** 364 ** Descriptions: The routine checks if a device is present at 365 ** the specified address. 366 ** 367 ** parameters: 8-bit address byte including the read bit 368 ** Returned value: True if a device ACKed, otherwise False 369 ** 370 *****************************************************************************/ 371 bool i2cCheckAddress( uint8_t addr ) 372 { 373 uint32_t i2cState; 374 375 // Send the addr byte and check for ACK 376 i2c_write_len = 1; 377 i2c_read_len = 0; 378 i2c_write_buf[0] = addr; 379 i2cState = i2cEngine(); 380 381 // Check if we got an ACK 382 if ((i2cState == I2CSTATE_NACK) || (i2cState == I2CSTATE_SLA_NACK)) 383 { 384 // I2C slave didn't acknowledge the master transfer 385 // The device probably isn't connected 386 return false; 387 } 388 else if (i2cState == I2CSTATE_TIMEOUT) 389 { 390 // I2C timed out waiting for start/stop 391 return false; 392 } 393 else 394 { 395 // I2C device found 396 return true; 397 } 398 } 399 400 /****************************************************************************** 401 ** End Of File 402 ******************************************************************************/ 403 404 #endif