C:/nxpdrv/LPC1700CMSIS/Drivers/source/lpc17xx_i2c.c
Go to the documentation of this file.00001 00020 /* Peripheral group ----------------------------------------------------------- */ 00025 /* Includes ------------------------------------------------------------------- */ 00026 #include "lpc17xx_i2c.h" 00027 #include "lpc17xx_clkpwr.h" 00028 #include "lpc17xx_pinsel.h" 00029 00030 00031 /* If this source file built with example, the LPC17xx FW library configuration 00032 * file in each example directory ("lpc17xx_libcfg.h") must be included, 00033 * otherwise the default FW library configuration file must be included instead 00034 */ 00035 #ifdef __BUILD_WITH_EXAMPLE__ 00036 #include "lpc17xx_libcfg.h" 00037 #else 00038 #include "lpc17xx_libcfg_default.h" 00039 #endif /* __BUILD_WITH_EXAMPLE__ */ 00040 00041 00042 #ifdef _I2C 00043 00044 00045 /* Private Types -------------------------------------------------------------- */ 00053 typedef struct 00054 { 00055 uint32_t txrx_setup; /* Transmission setup */ 00056 int32_t dir; /* Current direction phase, 0 - write, 1 - read */ 00057 void (*inthandler)(LPC_I2C_TypeDef *I2Cx); /* Transmission interrupt handler */ 00058 } I2C_CFG_T; 00059 00064 /* Private Variables ---------------------------------------------------------- */ 00068 static I2C_CFG_T i2cdat[3]; 00069 00070 00071 00072 /* Private Functions ---------------------------------------------------------- */ 00077 /* Generate a start condition on I2C bus (in master mode only) */ 00078 static uint32_t I2C_Start (LPC_I2C_TypeDef *I2Cx); 00079 00080 /* Generate a stop condition on I2C bus (in master mode only) */ 00081 static void I2C_Stop (LPC_I2C_TypeDef *I2Cx); 00082 00083 /* I2C send byte subroutine */ 00084 static uint32_t I2C_SendByte (LPC_I2C_TypeDef *I2Cx, uint8_t databyte); 00085 00086 /* I2C get byte subroutine */ 00087 static uint32_t I2C_GetByte (LPC_I2C_TypeDef *I2Cx, uint8_t *retdat, Bool ack); 00088 00089 /* I2C interrupt master handler */ 00090 void I2C_MasterHandler (LPC_I2C_TypeDef *I2Cx); 00091 00092 /* I2C interrupt master handler */ 00093 void I2C_SlaveHandler (LPC_I2C_TypeDef *I2Cx); 00094 00095 /* Enable interrupt for I2C device */ 00096 void I2C_IntCmd (LPC_I2C_TypeDef *I2Cx, Bool NewState); 00097 00098 /*--------------------------------------------------------------------------------*/ 00099 00103 static int32_t I2C_getNum(LPC_I2C_TypeDef *I2Cx){ 00104 if (I2Cx == LPC_I2C0) { 00105 return (0); 00106 } else if (I2Cx == LPC_I2C1) { 00107 return (1); 00108 } else if (I2Cx == LPC_I2C2) { 00109 return (2); 00110 } 00111 return (-1); 00112 } 00113 00114 /*********************************************************************** 00115 * Function: I2C_Start 00116 * Purpose: Generate a start condition on I2C bus (in master mode only) 00117 * Parameters: 00118 * i2cdev: Pointer to I2C register 00119 * blocking: blocking or none blocking mode 00120 * Returns: value of I2C status register after generate a start condition 00121 **********************************************************************/ 00122 static uint32_t I2C_Start (LPC_I2C_TypeDef *I2Cx) 00123 { 00124 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00125 I2Cx->I2CONSET = I2C_I2CONSET_STA; 00126 00127 // Wait for complete 00128 while (!(I2Cx->I2CONSET & I2C_I2CONSET_SI)); 00129 I2Cx->I2CONCLR = I2C_I2CONCLR_STAC; 00130 return (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK); 00131 } 00132 00133 00134 /*********************************************************************** 00135 * Function: I2C_Stop 00136 * Purpose: Generate a stop condition on I2C bus (in master mode only) 00137 * Parameters: 00138 * I2Cx: Pointer to I2C register 00139 * Returns: None 00140 **********************************************************************/ 00141 static void I2C_Stop (LPC_I2C_TypeDef *I2Cx) 00142 { 00143 00144 /* Make sure start bit is not active */ 00145 if (I2Cx->I2CONSET & I2C_I2CONSET_STA) 00146 { 00147 I2Cx->I2CONCLR = I2C_I2CONCLR_STAC; 00148 } 00149 I2Cx->I2CONSET = I2C_I2CONSET_STO; 00150 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00151 } 00152 00153 00154 /*********************************************************************** 00155 * Function: I2C_SendByte 00156 * Purpose: Send a byte 00157 * Parameters: 00158 * I2Cx: Pointer to I2C register 00159 * Returns: value of I2C status register after sending 00160 **********************************************************************/ 00161 static uint32_t I2C_SendByte (LPC_I2C_TypeDef *I2Cx, uint8_t databyte) 00162 { 00163 /* Make sure start bit is not active */ 00164 if (I2Cx->I2CONSET & I2C_I2CONSET_STA) 00165 { 00166 I2Cx->I2CONCLR = I2C_I2CONCLR_STAC; 00167 } 00168 I2Cx->I2DAT = databyte & I2C_I2DAT_BITMASK; 00169 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00170 00171 while (!(I2Cx->I2CONSET & I2C_I2CONSET_SI)); 00172 return (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK); 00173 } 00174 00175 00176 /*********************************************************************** 00177 * Function: I2C_GetByte 00178 * Purpose: Get a byte 00179 * Parameters: 00180 * I2Cx: Pointer to I2C register 00181 * Returns: value of I2C status register after receiving 00182 **********************************************************************/ 00183 static uint32_t I2C_GetByte (LPC_I2C_TypeDef *I2Cx, uint8_t *retdat, Bool ack) 00184 { 00185 if (ack == TRUE) 00186 { 00187 I2Cx->I2CONSET = I2C_I2CONSET_AA; 00188 } 00189 else 00190 { 00191 I2Cx->I2CONCLR = I2C_I2CONCLR_AAC; 00192 } 00193 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00194 00195 while (!(I2Cx->I2CONSET & I2C_I2CONSET_SI)); 00196 *retdat = (uint8_t) (I2Cx->I2DAT & I2C_I2DAT_BITMASK); 00197 return (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK); 00198 } 00199 00200 00201 00202 /*********************************************************************/ 00211 void I2C_IntCmd (LPC_I2C_TypeDef *I2Cx, Bool NewState) 00212 { 00213 if (NewState) 00214 { 00215 if(I2Cx == LPC_I2C0) 00216 { 00217 NVIC_EnableIRQ(I2C0_IRQn); 00218 } 00219 else if (I2Cx == LPC_I2C1) 00220 { 00221 NVIC_EnableIRQ(I2C1_IRQn); 00222 } 00223 else if (I2Cx == LPC_I2C2) 00224 { 00225 NVIC_EnableIRQ(I2C2_IRQn); 00226 } 00227 } 00228 else 00229 { 00230 if(I2Cx == LPC_I2C0) 00231 { 00232 NVIC_DisableIRQ(I2C0_IRQn); 00233 } 00234 else if (I2Cx == LPC_I2C1) 00235 { 00236 NVIC_DisableIRQ(I2C1_IRQn); 00237 } 00238 else if (I2Cx == LPC_I2C2) 00239 { 00240 NVIC_DisableIRQ(I2C2_IRQn); 00241 } 00242 } 00243 return; 00244 } 00245 00246 00247 /*********************************************************************/ 00252 void I2C_MasterHandler (LPC_I2C_TypeDef *I2Cx) 00253 { 00254 int32_t tmp; 00255 uint8_t returnCode; 00256 I2C_M_SETUP_Type *txrx_setup; 00257 00258 tmp = I2C_getNum(I2Cx); 00259 txrx_setup = (I2C_M_SETUP_Type *) i2cdat[tmp].txrx_setup; 00260 00261 returnCode = (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK); 00262 // Save current status 00263 txrx_setup->status = returnCode; 00264 // there's no relevant information 00265 if (returnCode == I2C_I2STAT_NO_INF){ 00266 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00267 return; 00268 } 00269 00270 /* ----------------------------- TRANSMIT PHASE --------------------------*/ 00271 if (i2cdat[tmp].dir == 0){ 00272 switch (returnCode) 00273 { 00274 /* A start/repeat start condition has been transmitted -------------------*/ 00275 case I2C_I2STAT_M_TX_START: 00276 case I2C_I2STAT_M_TX_RESTART: 00277 I2Cx->I2CONCLR = I2C_I2CONCLR_STAC; 00278 /* 00279 * If there's any transmit data, then start to 00280 * send SLA+W right now, otherwise check whether if there's 00281 * any receive data for next state. 00282 */ 00283 if ((txrx_setup->tx_data != NULL) && (txrx_setup->tx_length != 0)){ 00284 I2Cx->I2DAT = (txrx_setup->sl_addr7bit << 1); 00285 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00286 } else { 00287 goto next_stage; 00288 } 00289 break; 00290 00291 /* SLA+W has been transmitted, ACK has been received ----------------------*/ 00292 case I2C_I2STAT_M_TX_SLAW_ACK: 00293 /* Data has been transmitted, ACK has been received */ 00294 case I2C_I2STAT_M_TX_DAT_ACK: 00295 /* Send more data */ 00296 if ((txrx_setup->tx_count < txrx_setup->tx_length) \ 00297 && (txrx_setup->tx_data != NULL)){ 00298 I2Cx->I2DAT = *(uint8_t *)(txrx_setup->tx_data + txrx_setup->tx_count); 00299 txrx_setup->tx_count++; 00300 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00301 } 00302 // no more data, switch to next stage 00303 else { 00304 next_stage: 00305 // change direction 00306 i2cdat[tmp].dir = 1; 00307 // Check if any data to receive 00308 if ((txrx_setup->rx_length != 0) && (txrx_setup->rx_data != NULL)){ 00309 // check whether if we need to issue an repeat start 00310 if ((txrx_setup->tx_length != 0) && (txrx_setup->tx_data != NULL)){ 00311 // Send out an repeat start command 00312 I2Cx->I2CONSET = I2C_I2CONSET_STA; 00313 I2Cx->I2CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC; 00314 } 00315 // Don't need issue an repeat start, just goto send SLA+R 00316 else { 00317 goto send_slar; 00318 } 00319 } 00320 // no more data send, the go to end stage now 00321 else { 00322 // success, goto end stage 00323 txrx_setup->status |= I2C_SETUP_STATUS_DONE; 00324 goto end_stage; 00325 } 00326 } 00327 break; 00328 00329 /* SLA+W has been transmitted, NACK has been received ----------------------*/ 00330 case I2C_I2STAT_M_TX_SLAW_NACK: 00331 /* Data has been transmitted, NACK has been received -----------------------*/ 00332 case I2C_I2STAT_M_TX_DAT_NACK: 00333 // update status 00334 txrx_setup->status |= I2C_SETUP_STATUS_NOACKF; 00335 goto retry; 00336 break; 00337 /* Arbitration lost in SLA+R/W or Data bytes -------------------------------*/ 00338 case I2C_I2STAT_M_TX_ARB_LOST: 00339 // update status 00340 txrx_setup->status |= I2C_SETUP_STATUS_ARBF; 00341 default: 00342 goto retry; 00343 break; 00344 } 00345 } 00346 00347 /* ----------------------------- RECEIVE PHASE --------------------------*/ 00348 else if (i2cdat[tmp].dir == 1){ 00349 switch (returnCode){ 00350 /* A start/repeat start condition has been transmitted ---------------------*/ 00351 case I2C_I2STAT_M_RX_START: 00352 case I2C_I2STAT_M_RX_RESTART: 00353 I2Cx->I2CONCLR = I2C_I2CONCLR_STAC; 00354 /* 00355 * If there's any receive data, then start to 00356 * send SLA+R right now, otherwise check whether if there's 00357 * any receive data for end of state. 00358 */ 00359 if ((txrx_setup->rx_data != NULL) && (txrx_setup->rx_length != 0)){ 00360 send_slar: 00361 I2Cx->I2DAT = (txrx_setup->sl_addr7bit << 1) | 0x01; 00362 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00363 } else { 00364 // Success, goto end stage 00365 txrx_setup->status |= I2C_SETUP_STATUS_DONE; 00366 goto end_stage; 00367 } 00368 break; 00369 00370 /* SLA+R has been transmitted, ACK has been received -----------------*/ 00371 case I2C_I2STAT_M_RX_SLAR_ACK: 00372 if (txrx_setup->rx_count < (txrx_setup->rx_length - 1)) { 00373 /*Data will be received, ACK will be return*/ 00374 I2Cx->I2CONSET = I2C_I2CONSET_AA; 00375 } 00376 else { 00377 /*Last data will be received, NACK will be return*/ 00378 I2Cx->I2CONCLR = I2C_I2CONSET_AA; 00379 } 00380 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00381 break; 00382 00383 /* Data has been received, ACK has been returned ----------------------*/ 00384 case I2C_I2STAT_M_RX_DAT_ACK: 00385 // Note save data and increase counter first, then check later 00386 /* Save data */ 00387 if ((txrx_setup->rx_data != NULL) && (txrx_setup->rx_count < txrx_setup->rx_length)){ 00388 *(uint8_t *)(txrx_setup->rx_data + txrx_setup->rx_count) = (I2Cx->I2DAT & I2C_I2DAT_BITMASK); 00389 txrx_setup->rx_count++; 00390 } 00391 if (txrx_setup->rx_count < (txrx_setup->rx_length - 1)) { 00392 /*Data will be received, ACK will be return*/ 00393 I2Cx->I2CONSET = I2C_I2CONSET_AA; 00394 } 00395 else { 00396 /*Last data will be received, NACK will be return*/ 00397 I2Cx->I2CONCLR = I2C_I2CONSET_AA; 00398 } 00399 00400 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00401 break; 00402 00403 /* Data has been received, NACK has been return -------------------------*/ 00404 case I2C_I2STAT_M_RX_DAT_NACK: 00405 /* Save the last data */ 00406 if ((txrx_setup->rx_data != NULL) && (txrx_setup->rx_count < txrx_setup->rx_length)){ 00407 *(uint8_t *)(txrx_setup->rx_data + txrx_setup->rx_count) = (I2Cx->I2DAT & I2C_I2DAT_BITMASK); 00408 txrx_setup->rx_count++; 00409 } 00410 // success, go to end stage 00411 txrx_setup->status |= I2C_SETUP_STATUS_DONE; 00412 goto end_stage; 00413 break; 00414 00415 /* SLA+R has been transmitted, NACK has been received ------------------*/ 00416 case I2C_I2STAT_M_RX_SLAR_NACK: 00417 // update status 00418 txrx_setup->status |= I2C_SETUP_STATUS_NOACKF; 00419 goto retry; 00420 break; 00421 00422 /* Arbitration lost ----------------------------------------------------*/ 00423 case I2C_I2STAT_M_RX_ARB_LOST: 00424 // update status 00425 txrx_setup->status |= I2C_SETUP_STATUS_ARBF; 00426 default: 00427 retry: 00428 // check if retransmission is available 00429 if (txrx_setup->retransmissions_count < txrx_setup->retransmissions_max){ 00430 // Clear tx count 00431 txrx_setup->tx_count = 0; 00432 I2Cx->I2CONSET = I2C_I2CONSET_STA; 00433 I2Cx->I2CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC; 00434 txrx_setup->retransmissions_count++; 00435 } 00436 // End of stage 00437 else { 00438 end_stage: 00439 // Disable interrupt 00440 I2C_IntCmd(I2Cx, 0); 00441 // Send stop 00442 I2C_Stop(I2Cx); 00443 // Call callback if installed 00444 if (txrx_setup->callback != NULL){ 00445 txrx_setup->callback(); 00446 } 00447 } 00448 break; 00449 } 00450 } 00451 } 00452 00453 00454 /*********************************************************************/ 00459 void I2C_SlaveHandler (LPC_I2C_TypeDef *I2Cx) 00460 { 00461 int32_t tmp; 00462 uint8_t returnCode; 00463 I2C_S_SETUP_Type *txrx_setup; 00464 uint32_t timeout; 00465 00466 tmp = I2C_getNum(I2Cx); 00467 txrx_setup = (I2C_S_SETUP_Type *) i2cdat[tmp].txrx_setup; 00468 00469 returnCode = (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK); 00470 // Save current status 00471 txrx_setup->status = returnCode; 00472 // there's no relevant information 00473 if (returnCode == I2C_I2STAT_NO_INF){ 00474 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00475 return; 00476 } 00477 00478 00479 switch (returnCode) 00480 { 00481 00482 /* No status information */ 00483 case I2C_I2STAT_NO_INF: 00484 I2Cx->I2CONSET = I2C_I2CONSET_AA; 00485 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00486 break; 00487 00488 /* Reading phase -------------------------------------------------------- */ 00489 /* Own SLA+R has been received, ACK has been returned */ 00490 case I2C_I2STAT_S_RX_SLAW_ACK: 00491 /* General call address has been received, ACK has been returned */ 00492 case I2C_I2STAT_S_RX_GENCALL_ACK: 00493 I2Cx->I2CONSET = I2C_I2CONSET_AA; 00494 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00495 break; 00496 00497 /* Previously addressed with own SLA; 00498 * DATA byte has been received; 00499 * ACK has been returned */ 00500 case I2C_I2STAT_S_RX_PRE_SLA_DAT_ACK: 00501 /* DATA has been received, ACK hasn been return */ 00502 case I2C_I2STAT_S_RX_PRE_GENCALL_DAT_ACK: 00503 /* 00504 * All data bytes that over-flow the specified receive 00505 * data length, just ignore them. 00506 */ 00507 if ((txrx_setup->rx_count < txrx_setup->rx_length) \ 00508 && (txrx_setup->rx_data != NULL)){ 00509 *(uint8_t *)(txrx_setup->rx_data + txrx_setup->rx_count) = (uint8_t)I2Cx->I2DAT; 00510 txrx_setup->rx_count++; 00511 } 00512 I2Cx->I2CONSET = I2C_I2CONSET_AA; 00513 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00514 break; 00515 00516 /* Previously addressed with own SLA; 00517 * DATA byte has been received; 00518 * NOT ACK has been returned */ 00519 case I2C_I2STAT_S_RX_PRE_SLA_DAT_NACK: 00520 /* DATA has been received, NOT ACK has been returned */ 00521 case I2C_I2STAT_S_RX_PRE_GENCALL_DAT_NACK: 00522 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00523 break; 00524 00525 /* 00526 * Note that: Return code only let us know a stop condition mixed 00527 * with a repeat start condition in the same code value. 00528 * So we should provide a time-out. In case this is really a stop 00529 * condition, this will return back after time out condition. Otherwise, 00530 * next session that is slave receive data will be completed. 00531 */ 00532 00533 /* A Stop or a repeat start condition */ 00534 case I2C_I2STAT_S_RX_STA_STO_SLVREC_SLVTRX: 00535 // Temporally lock the interrupt for timeout condition 00536 I2C_IntCmd(I2Cx, 0); 00537 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00538 // enable time out 00539 timeout = I2C_SLAVE_TIME_OUT; 00540 while(1){ 00541 if (I2Cx->I2CONSET & I2C_I2CONSET_SI){ 00542 // re-Enable interrupt 00543 I2C_IntCmd(I2Cx, 1); 00544 break; 00545 } else { 00546 timeout--; 00547 if (timeout == 0){ 00548 // timeout occur, it's really a stop condition 00549 txrx_setup->status |= I2C_SETUP_STATUS_DONE; 00550 goto s_int_end; 00551 } 00552 } 00553 } 00554 break; 00555 00556 /* Writing phase -------------------------------------------------------- */ 00557 /* Own SLA+R has been received, ACK has been returned */ 00558 case I2C_I2STAT_S_TX_SLAR_ACK: 00559 /* Data has been transmitted, ACK has been received */ 00560 case I2C_I2STAT_S_TX_DAT_ACK: 00561 /* 00562 * All data bytes that over-flow the specified receive 00563 * data length, just ignore them. 00564 */ 00565 if ((txrx_setup->tx_count < txrx_setup->tx_length) \ 00566 && (txrx_setup->tx_data != NULL)){ 00567 I2Cx->I2DAT = *(uint8_t *) (txrx_setup->tx_data + txrx_setup->tx_count); 00568 txrx_setup->tx_count++; 00569 } 00570 I2Cx->I2CONSET = I2C_I2CONSET_AA; 00571 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00572 break; 00573 00574 /* Data has been transmitted, NACK has been received, 00575 * that means there's no more data to send, exit now */ 00576 /* 00577 * Note: Don't wait for stop event since in slave transmit mode, 00578 * since there no proof lets us know when a stop signal has been received 00579 * on slave side. 00580 */ 00581 case I2C_I2STAT_S_TX_DAT_NACK: 00582 I2Cx->I2CONSET = I2C_I2CONSET_AA; 00583 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00584 txrx_setup->status |= I2C_SETUP_STATUS_DONE; 00585 goto s_int_end; 00586 break; 00587 00588 // Other status must be captured 00589 default: 00590 s_int_end: 00591 // Disable interrupt 00592 I2C_IntCmd(I2Cx, 0); 00593 I2Cx->I2CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC; 00594 // Call callback if installed 00595 if (txrx_setup->callback != NULL){ 00596 txrx_setup->callback(); 00597 } 00598 break; 00599 } 00600 } 00601 00607 /* Public Functions ----------------------------------------------------------- */ 00612 /*********************************************************************/ 00618 void I2C_SetClock (LPC_I2C_TypeDef *I2Cx, uint32_t target_clock) 00619 { 00620 uint32_t temp; 00621 00622 CHECK_PARAM(PARAM_I2Cx(I2Cx)); 00623 00624 // Get PCLK of I2C controller 00625 if (I2Cx == LPC_I2C0) 00626 { 00627 temp = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_I2C0) / target_clock; 00628 } 00629 else if (I2Cx == LPC_I2C1) 00630 { 00631 temp = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_I2C1) / target_clock; 00632 } 00633 else if (I2Cx == LPC_I2C2) 00634 { 00635 temp = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_I2C1) / target_clock; 00636 } 00637 00638 /* Set the I2C clock value to register */ 00639 I2Cx->I2SCLH = (uint32_t)(temp / 2); 00640 I2Cx->I2SCLL = (uint32_t)(temp - I2Cx->I2SCLH); 00641 } 00642 00643 00644 /*********************************************************************/ 00650 void I2C_DeInit(LPC_I2C_TypeDef* I2Cx) 00651 { 00652 CHECK_PARAM(PARAM_I2Cx(I2Cx)); 00653 00654 /* Disable I2C control */ 00655 I2Cx->I2CONCLR = I2C_I2CONCLR_I2ENC; 00656 00657 if (I2Cx==LPC_I2C0) 00658 { 00659 /* Disable power for I2C0 module */ 00660 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C0, DISABLE); 00661 } 00662 else if (I2Cx==LPC_I2C1) 00663 { 00664 /* Disable power for I2C1 module */ 00665 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C1, DISABLE); 00666 } 00667 else if (I2Cx==LPC_I2C2) 00668 { 00669 /* Disable power for I2C2 module */ 00670 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C2, DISABLE); 00671 } 00672 } 00673 00674 00675 /********************************************************************/ 00682 void I2C_Init(LPC_I2C_TypeDef *I2Cx, uint32_t clockrate) 00683 { 00684 CHECK_PARAM(PARAM_I2Cx(I2Cx)); 00685 00686 if (I2Cx==LPC_I2C0) 00687 { 00688 /* Set up clock and power for I2C0 module */ 00689 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C0, ENABLE); 00690 /* As default, peripheral clock for I2C0 module 00691 * is set to FCCLK / 2 */ 00692 CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_I2C0, CLKPWR_PCLKSEL_CCLK_DIV_2); 00693 } 00694 else if (I2Cx==LPC_I2C1) 00695 { 00696 /* Set up clock and power for I2C1 module */ 00697 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C1, ENABLE); 00698 /* As default, peripheral clock for I2C1 module 00699 * is set to FCCLK / 2 */ 00700 CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_I2C1, CLKPWR_PCLKSEL_CCLK_DIV_2); 00701 } 00702 else if (I2Cx==LPC_I2C2) 00703 { 00704 /* Set up clock and power for I2C2 module */ 00705 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C2, ENABLE); 00706 /* As default, peripheral clock for I2C2 module 00707 * is set to FCCLK / 2 */ 00708 CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_I2C2, CLKPWR_PCLKSEL_CCLK_DIV_2); 00709 } 00710 else { 00711 // Up-Support this device 00712 return; 00713 } 00714 00715 /* Set clock rate */ 00716 I2C_SetClock(I2Cx, clockrate); 00717 /* Set I2C operation to default */ 00718 I2Cx->I2CONCLR = (I2C_I2CONCLR_AAC | I2C_I2CONCLR_STAC | I2C_I2CONCLR_I2ENC); 00719 } 00720 00721 00722 /*********************************************************************/ 00728 void I2C_Cmd(LPC_I2C_TypeDef* I2Cx, FunctionalState NewState) 00729 { 00730 CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); 00731 CHECK_PARAM(PARAM_I2Cx(I2Cx)); 00732 00733 if (NewState == ENABLE) 00734 { 00735 I2Cx->I2CONSET = I2C_I2CONSET_I2EN; 00736 } 00737 else 00738 { 00739 I2Cx->I2CONCLR = I2C_I2CONCLR_I2ENC; 00740 } 00741 } 00742 00743 00744 /*********************************************************************/ 00763 Status I2C_MasterTransferData(LPC_I2C_TypeDef *I2Cx, I2C_M_SETUP_Type *TransferCfg, \ 00764 I2C_TRANSFER_OPT_Type Opt) 00765 { 00766 uint8_t *txdat; 00767 uint8_t *rxdat; 00768 uint32_t CodeStatus; 00769 uint8_t tmp; 00770 00771 // reset all default state 00772 txdat = (uint8_t *) TransferCfg->tx_data; 00773 rxdat = (uint8_t *) TransferCfg->rx_data; 00774 // Reset I2C setup value to default state 00775 TransferCfg->tx_count = 0; 00776 TransferCfg->rx_count = 0; 00777 TransferCfg->status = 0; 00778 00779 if (Opt == I2C_TRANSFER_POLLING){ 00780 00781 /* First Start condition -------------------------------------------------------------- */ 00782 TransferCfg->retransmissions_count = 0; 00783 retry: 00784 // reset all default state 00785 txdat = (uint8_t *) TransferCfg->tx_data; 00786 rxdat = (uint8_t *) TransferCfg->rx_data; 00787 // Reset I2C setup value to default state 00788 TransferCfg->tx_count = 0; 00789 TransferCfg->rx_count = 0; 00790 CodeStatus = 0; 00791 00792 // Start command 00793 CodeStatus = I2C_Start(I2Cx); 00794 if ((CodeStatus != I2C_I2STAT_M_TX_START) \ 00795 && (CodeStatus != I2C_I2STAT_M_TX_RESTART)){ 00796 TransferCfg->retransmissions_count++; 00797 if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ 00798 // save status 00799 TransferCfg->status = CodeStatus; 00800 goto error; 00801 } else { 00802 goto retry; 00803 } 00804 } 00805 00806 /* In case of sending data first --------------------------------------------------- */ 00807 if ((TransferCfg->tx_length != 0) && (TransferCfg->tx_data != NULL)){ 00808 00809 /* Send slave address + WR direction bit = 0 ----------------------------------- */ 00810 CodeStatus = I2C_SendByte(I2Cx, (TransferCfg->sl_addr7bit << 1)); 00811 if (CodeStatus != I2C_I2STAT_M_TX_SLAW_ACK){ 00812 TransferCfg->retransmissions_count++; 00813 if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ 00814 // save status 00815 TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_NOACKF; 00816 goto error; 00817 } else { 00818 goto retry; 00819 } 00820 } 00821 00822 /* Send a number of data bytes ---------------------------------------- */ 00823 while (TransferCfg->tx_count < TransferCfg->tx_length) 00824 { 00825 CodeStatus = I2C_SendByte(I2Cx, *txdat); 00826 if (CodeStatus != I2C_I2STAT_M_TX_DAT_ACK){ 00827 TransferCfg->retransmissions_count++; 00828 if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ 00829 // save status 00830 TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_NOACKF; 00831 goto error; 00832 } else { 00833 goto retry; 00834 } 00835 } 00836 00837 txdat++; 00838 TransferCfg->tx_count++; 00839 } 00840 } 00841 00842 /* Second Start condition (Repeat Start) ------------------------------------------- */ 00843 if ((TransferCfg->tx_length != 0) && (TransferCfg->tx_data != NULL) \ 00844 && (TransferCfg->rx_length != 0) && (TransferCfg->rx_data != NULL)){ 00845 00846 CodeStatus = I2C_Start(I2Cx); 00847 if ((CodeStatus != I2C_I2STAT_M_RX_START) \ 00848 && (CodeStatus != I2C_I2STAT_M_RX_RESTART)){ 00849 TransferCfg->retransmissions_count++; 00850 if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ 00851 // Update status 00852 TransferCfg->status = CodeStatus; 00853 goto error; 00854 } else { 00855 goto retry; 00856 } 00857 } 00858 } 00859 00860 /* Then, start reading after sending data -------------------------------------- */ 00861 if ((TransferCfg->rx_length != 0) && (TransferCfg->rx_data != NULL)){ 00862 /* Send slave address + RD direction bit = 1 ----------------------------------- */ 00863 00864 CodeStatus = I2C_SendByte(I2Cx, ((TransferCfg->sl_addr7bit << 1) | 0x01)); 00865 if (CodeStatus != I2C_I2STAT_M_RX_SLAR_ACK){ 00866 TransferCfg->retransmissions_count++; 00867 if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ 00868 // update status 00869 TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_NOACKF; 00870 goto error; 00871 } else { 00872 goto retry; 00873 } 00874 } 00875 00876 /* Receive a number of data bytes ------------------------------------------------- */ 00877 while (TransferCfg->rx_count < TransferCfg->rx_length){ 00878 00879 /* 00880 * Note that: if data length is only one, the master should not 00881 * issue an ACK signal on bus after reading to avoid of next data frame 00882 * on slave side 00883 */ 00884 if (TransferCfg->rx_count < (TransferCfg->rx_length - 1)){ 00885 // Issue an ACK signal for next data frame 00886 CodeStatus = I2C_GetByte(I2Cx, &tmp, 1); 00887 if (CodeStatus != I2C_I2STAT_M_RX_DAT_ACK){ 00888 TransferCfg->retransmissions_count++; 00889 if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ 00890 // update status 00891 TransferCfg->status = CodeStatus; 00892 goto error; 00893 } else { 00894 goto retry; 00895 } 00896 } 00897 } else { 00898 // Do not issue an ACK signal 00899 CodeStatus = I2C_GetByte(I2Cx, &tmp, 0); 00900 if (CodeStatus != I2C_I2STAT_M_RX_DAT_NACK){ 00901 TransferCfg->retransmissions_count++; 00902 if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ 00903 // update status 00904 TransferCfg->status = CodeStatus; 00905 goto error; 00906 } else { 00907 goto retry; 00908 } 00909 } 00910 } 00911 *rxdat++ = tmp; 00912 TransferCfg->rx_count++; 00913 } 00914 } 00915 00916 /* Send STOP condition ------------------------------------------------- */ 00917 I2C_Stop(I2Cx); 00918 return SUCCESS; 00919 00920 error: 00921 // Send stop condition 00922 I2C_Stop(I2Cx); 00923 return ERROR; 00924 } 00925 00926 else if (Opt == I2C_TRANSFER_INTERRUPT){ 00927 // Setup tx_rx data, callback and interrupt handler 00928 tmp = I2C_getNum(I2Cx); 00929 i2cdat[tmp].txrx_setup = (uint32_t) TransferCfg; 00930 i2cdat[tmp].inthandler = I2C_MasterHandler; 00931 // Set direction phase, write first 00932 i2cdat[tmp].dir = 0; 00933 00934 /* First Start condition -------------------------------------------------------------- */ 00935 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00936 I2Cx->I2CONSET = I2C_I2CONSET_STA; 00937 I2C_IntCmd(I2Cx, 1); 00938 00939 return (SUCCESS); 00940 } 00941 00942 return ERROR; 00943 } 00944 00945 /*********************************************************************/ 00973 Status I2C_SlaveTransferData(LPC_I2C_TypeDef *I2Cx, I2C_S_SETUP_Type *TransferCfg, \ 00974 I2C_TRANSFER_OPT_Type Opt) 00975 { 00976 uint8_t *txdat; 00977 uint8_t *rxdat; 00978 uint32_t CodeStatus; 00979 uint32_t timeout; 00980 int32_t time_en; 00981 int32_t tmp; 00982 00983 // reset all default state 00984 txdat = (uint8_t *) TransferCfg->tx_data; 00985 rxdat = (uint8_t *) TransferCfg->rx_data; 00986 // Reset I2C setup value to default state 00987 TransferCfg->tx_count = 0; 00988 TransferCfg->rx_count = 0; 00989 TransferCfg->status = 0; 00990 00991 00992 // Polling option 00993 if (Opt == I2C_TRANSFER_POLLING){ 00994 00995 /* Set AA bit to ACK command on I2C bus */ 00996 I2Cx->I2CONSET = I2C_I2CONSET_AA; 00997 /* Clear SI bit to be ready ... */ 00998 I2Cx->I2CONCLR = (I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC); 00999 01000 time_en = 0; 01001 timeout = 0; 01002 01003 while (1) 01004 { 01005 /* Check SI flag ready */ 01006 if (I2Cx->I2CONSET & I2C_I2CONSET_SI) 01007 { 01008 time_en = 0; 01009 01010 switch (CodeStatus = (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK)) 01011 { 01012 01013 /* No status information */ 01014 case I2C_I2STAT_NO_INF: 01015 I2Cx->I2CONSET = I2C_I2CONSET_AA; 01016 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 01017 break; 01018 01019 /* Reading phase -------------------------------------------------------- */ 01020 /* Own SLA+R has been received, ACK has been returned */ 01021 case I2C_I2STAT_S_RX_SLAW_ACK: 01022 /* General call address has been received, ACK has been returned */ 01023 case I2C_I2STAT_S_RX_GENCALL_ACK: 01024 I2Cx->I2CONSET = I2C_I2CONSET_AA; 01025 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 01026 break; 01027 01028 /* Previously addressed with own SLA; 01029 * DATA byte has been received; 01030 * ACK has been returned */ 01031 case I2C_I2STAT_S_RX_PRE_SLA_DAT_ACK: 01032 /* DATA has been received, ACK hasn been return */ 01033 case I2C_I2STAT_S_RX_PRE_GENCALL_DAT_ACK: 01034 /* 01035 * All data bytes that over-flow the specified receive 01036 * data length, just ignore them. 01037 */ 01038 if ((TransferCfg->rx_count < TransferCfg->rx_length) \ 01039 && (TransferCfg->rx_data != NULL)){ 01040 *rxdat++ = (uint8_t)I2Cx->I2DAT; 01041 TransferCfg->rx_count++; 01042 } 01043 I2Cx->I2CONSET = I2C_I2CONSET_AA; 01044 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 01045 break; 01046 01047 /* Previously addressed with own SLA; 01048 * DATA byte has been received; 01049 * NOT ACK has been returned */ 01050 case I2C_I2STAT_S_RX_PRE_SLA_DAT_NACK: 01051 /* DATA has been received, NOT ACK has been returned */ 01052 case I2C_I2STAT_S_RX_PRE_GENCALL_DAT_NACK: 01053 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 01054 break; 01055 01056 /* 01057 * Note that: Return code only let us know a stop condition mixed 01058 * with a repeat start condition in the same code value. 01059 * So we should provide a time-out. In case this is really a stop 01060 * condition, this will return back after time out condition. Otherwise, 01061 * next session that is slave receive data will be completed. 01062 */ 01063 01064 /* A Stop or a repeat start condition */ 01065 case I2C_I2STAT_S_RX_STA_STO_SLVREC_SLVTRX: 01066 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 01067 // enable time out 01068 time_en = 1; 01069 timeout = 0; 01070 break; 01071 01072 /* Writing phase -------------------------------------------------------- */ 01073 /* Own SLA+R has been received, ACK has been returned */ 01074 case I2C_I2STAT_S_TX_SLAR_ACK: 01075 /* Data has been transmitted, ACK has been received */ 01076 case I2C_I2STAT_S_TX_DAT_ACK: 01077 /* 01078 * All data bytes that over-flow the specified receive 01079 * data length, just ignore them. 01080 */ 01081 if ((TransferCfg->tx_count < TransferCfg->tx_length) \ 01082 && (TransferCfg->tx_data != NULL)){ 01083 I2Cx->I2DAT = *txdat++; 01084 TransferCfg->tx_count++; 01085 } 01086 I2Cx->I2CONSET = I2C_I2CONSET_AA; 01087 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 01088 break; 01089 01090 /* Data has been transmitted, NACK has been received, 01091 * that means there's no more data to send, exit now */ 01092 /* 01093 * Note: Don't wait for stop event since in slave transmit mode, 01094 * since there no proof lets us know when a stop signal has been received 01095 * on slave side. 01096 */ 01097 case I2C_I2STAT_S_TX_DAT_NACK: 01098 I2Cx->I2CONSET = I2C_I2CONSET_AA; 01099 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 01100 // enable time out 01101 time_en = 1; 01102 timeout = 0; 01103 break; 01104 01105 // Other status must be captured 01106 default: 01107 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 01108 goto s_error; 01109 break; 01110 } 01111 } else if (time_en){ 01112 if (timeout++ > I2C_SLAVE_TIME_OUT){ 01113 // it's really a stop condition, goto end stage 01114 goto s_end_stage; 01115 } 01116 } 01117 } 01118 01119 s_end_stage: 01120 /* Clear AA bit to disable ACK on I2C bus */ 01121 I2Cx->I2CONCLR = I2C_I2CONCLR_AAC; 01122 // Check if there's no error during operation 01123 // Update status 01124 TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_DONE; 01125 return SUCCESS; 01126 01127 s_error: 01128 /* Clear AA bit to disable ACK on I2C bus */ 01129 I2Cx->I2CONCLR = I2C_I2CONCLR_AAC; 01130 // Update status 01131 TransferCfg->status = CodeStatus; 01132 return ERROR; 01133 } 01134 01135 else if (Opt == I2C_TRANSFER_INTERRUPT){ 01136 // Setup tx_rx data, callback and interrupt handler 01137 tmp = I2C_getNum(I2Cx); 01138 i2cdat[tmp].txrx_setup = (uint32_t) TransferCfg; 01139 i2cdat[tmp].inthandler = I2C_SlaveHandler; 01140 // Set direction phase, read first 01141 i2cdat[tmp].dir = 1; 01142 01143 // Enable AA 01144 I2Cx->I2CONSET = I2C_I2CONSET_AA; 01145 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC; 01146 I2C_IntCmd(I2Cx, 1); 01147 01148 return (SUCCESS); 01149 } 01150 01151 return ERROR; 01152 } 01153 01154 /*********************************************************************/ 01163 void I2C_SetOwnSlaveAddr(LPC_I2C_TypeDef *I2Cx, I2C_OWNSLAVEADDR_CFG_Type *OwnSlaveAddrConfigStruct) 01164 { 01165 uint32_t tmp; 01166 CHECK_PARAM(PARAM_I2Cx(I2Cx)); 01167 CHECK_PARAM(PARAM_I2C_SLAVEADDR_CH(OwnSlaveAddrConfigStruct->SlaveAddrChannel)); 01168 CHECK_PARAM(PARAM_FUNCTIONALSTATE(OwnSlaveAddrConfigStruct->GeneralCallState)); 01169 01170 tmp = (((uint32_t)(OwnSlaveAddrConfigStruct->SlaveAddr_7bit << 1)) \ 01171 | ((OwnSlaveAddrConfigStruct->GeneralCallState == ENABLE) ? 0x01 : 0x00))& I2C_I2ADR_BITMASK; 01172 switch (OwnSlaveAddrConfigStruct->SlaveAddrChannel) 01173 { 01174 case 0: 01175 I2Cx->I2ADR0 = tmp; 01176 I2Cx->I2MASK0 = I2C_I2MASK_MASK((uint32_t) \ 01177 (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue)); 01178 break; 01179 case 1: 01180 I2Cx->I2ADR1 = tmp; 01181 I2Cx->I2MASK1 = I2C_I2MASK_MASK((uint32_t) \ 01182 (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue)); 01183 break; 01184 case 2: 01185 I2Cx->I2ADR2 = tmp; 01186 I2Cx->I2MASK2 = I2C_I2MASK_MASK((uint32_t) \ 01187 (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue)); 01188 break; 01189 case 3: 01190 I2Cx->I2ADR3 = tmp; 01191 I2Cx->I2MASK3 = I2C_I2MASK_MASK((uint32_t) \ 01192 (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue)); 01193 break; 01194 } 01195 } 01196 01197 01198 /*********************************************************************/ 01213 void I2C_MonitorModeConfig(LPC_I2C_TypeDef *I2Cx, uint32_t MonitorCfgType, FunctionalState NewState) 01214 { 01215 CHECK_PARAM(PARAM_I2Cx(I2Cx)); 01216 CHECK_PARAM(PARAM_I2C_MONITOR_CFG(MonitorCfgType)); 01217 CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); 01218 01219 if (NewState == ENABLE) 01220 { 01221 I2Cx->MMCTRL |= MonitorCfgType; 01222 } 01223 else 01224 { 01225 I2Cx->MMCTRL &= (~MonitorCfgType) & I2C_I2MMCTRL_BITMASK; 01226 } 01227 } 01228 01229 01230 /*********************************************************************/ 01238 void I2C_MonitorModeCmd(LPC_I2C_TypeDef *I2Cx, FunctionalState NewState) 01239 { 01240 CHECK_PARAM(PARAM_I2Cx(I2Cx)); 01241 CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); 01242 01243 if (NewState == ENABLE) 01244 { 01245 I2Cx->MMCTRL |= I2C_I2MMCTRL_MM_ENA; 01246 } 01247 else 01248 { 01249 I2Cx->MMCTRL &= (~I2C_I2MMCTRL_MM_ENA) & I2C_I2MMCTRL_BITMASK; 01250 } 01251 } 01252 01253 01254 /*********************************************************************/ 01266 uint8_t I2C_MonitorGetDatabuffer(LPC_I2C_TypeDef *I2Cx) 01267 { 01268 CHECK_PARAM(PARAM_I2Cx(I2Cx)); 01269 return ((uint8_t)(I2Cx->I2DATA_BUFFER)); 01270 } 01271 01272 /*********************************************************************/ 01277 void I2C0_StdIntHandler(void) 01278 { 01279 i2cdat[0].inthandler(LPC_I2C0); 01280 } 01281 01282 /*********************************************************************/ 01287 void I2C1_StdIntHandler(void) 01288 { 01289 i2cdat[1].inthandler(LPC_I2C1); 01290 } 01291 01292 /*********************************************************************/ 01297 void I2C2_StdIntHandler(void) 01298 { 01299 i2cdat[2].inthandler(LPC_I2C2); 01300 } 01301 01302 01307 #endif /* _I2C */ 01308 01313 /* --------------------------------- End Of File ------------------------------ */
Generated on Mon Feb 8 10:01:37 2010 for LPC1700CMSIS Standard Peripheral Firmware Library by 1.5.9