NXP's driver library for LPC17xx, ported to mbed's online compiler. Not tested! I had to fix a lot of warings and found a couple of pretty obvious bugs, so the chances are there are more. Original: http://ics.nxp.com/support/documents/microcontrollers/zip/lpc17xx.cmsis.driver.library.zip
lpc17xx_i2c.c
00001 /** 00002 * @file : lpc17xx_i2c.c 00003 * @brief : Contains all functions support for I2C firmware library on LPC17xx 00004 * @version : 1.0 00005 * @date : 9. April. 2009 00006 * @author : HieuNguyen 00007 ************************************************************************** 00008 * Software that is described herein is for illustrative purposes only 00009 * which provides customers with programming information regarding the 00010 * products. This software is supplied "AS IS" without any warranties. 00011 * NXP Semiconductors assumes no responsibility or liability for the 00012 * use of the software, conveys no license or title under any patent, 00013 * copyright, or mask work right to the product. NXP Semiconductors 00014 * reserves the right to make changes in the software without 00015 * notification. NXP Semiconductors also make no representation or 00016 * warranty that such application will be suitable for the specified 00017 * use without further testing or modification. 00018 **********************************************************************/ 00019 00020 /* Peripheral group ----------------------------------------------------------- */ 00021 /** @addtogroup I2C 00022 * @{ 00023 */ 00024 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 -------------------------------------------------------------- */ 00046 /** @defgroup I2C_Private_Types 00047 * @{ 00048 */ 00049 00050 /** 00051 * @brief I2C device configuration structure type 00052 */ 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 00060 /** 00061 * @} 00062 */ 00063 00064 /* Private Variables ---------------------------------------------------------- */ 00065 /** 00066 * @brief II2C driver data for I2C0, I2C1 and I2C2 00067 */ 00068 static I2C_CFG_T i2cdat[3]; 00069 00070 00071 00072 /* Private Functions ---------------------------------------------------------- */ 00073 /** @defgroup I2C_Private_Functions 00074 * @{ 00075 */ 00076 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, FunctionalState NewState); 00097 00098 /*--------------------------------------------------------------------------------*/ 00099 00100 /** 00101 * @brief Convert from I2C peripheral to number 00102 */ 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 /*********************************************************************//** 00203 * @brief Enable/Disable interrupt for I2C peripheral 00204 * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2 00205 * @param[in] NewState New State of I2C peripheral interrupt in NVIC core 00206 * should be: 00207 * - ENABLE: enable interrupt for this I2C peripheral 00208 * - DISABLE: disable interrupt for this I2C peripheral 00209 * @return None 00210 **********************************************************************/ 00211 void I2C_IntCmd (LPC_I2C_TypeDef *I2Cx, FunctionalState NewState) 00212 { 00213 if (NewState == ENABLE) 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 /*********************************************************************//** 00248 * @brief General Master Interrupt handler for I2C peripheral 00249 * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2 00250 * @return None 00251 **********************************************************************/ 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 /* Arbitration lost in SLA+R/W or Data bytes -------------------------------*/ 00337 case I2C_I2STAT_M_TX_ARB_LOST: 00338 // update status 00339 txrx_setup->status |= I2C_SETUP_STATUS_ARBF; 00340 default: 00341 goto retry; 00342 } 00343 } 00344 00345 /* ----------------------------- RECEIVE PHASE --------------------------*/ 00346 else if (i2cdat[tmp].dir == 1){ 00347 switch (returnCode){ 00348 /* A start/repeat start condition has been transmitted ---------------------*/ 00349 case I2C_I2STAT_M_RX_START: 00350 case I2C_I2STAT_M_RX_RESTART: 00351 I2Cx->I2CONCLR = I2C_I2CONCLR_STAC; 00352 /* 00353 * If there's any receive data, then start to 00354 * send SLA+R right now, otherwise check whether if there's 00355 * any receive data for end of state. 00356 */ 00357 if ((txrx_setup->rx_data != NULL) && (txrx_setup->rx_length != 0)){ 00358 send_slar: 00359 I2Cx->I2DAT = (txrx_setup->sl_addr7bit << 1) | 0x01; 00360 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00361 } else { 00362 // Success, goto end stage 00363 txrx_setup->status |= I2C_SETUP_STATUS_DONE; 00364 goto end_stage; 00365 } 00366 break; 00367 00368 /* SLA+R has been transmitted, ACK has been received -----------------*/ 00369 case I2C_I2STAT_M_RX_SLAR_ACK: 00370 if (txrx_setup->rx_count < (txrx_setup->rx_length - 1)) { 00371 /*Data will be received, ACK will be return*/ 00372 I2Cx->I2CONSET = I2C_I2CONSET_AA; 00373 } 00374 else { 00375 /*Last data will be received, NACK will be return*/ 00376 I2Cx->I2CONCLR = I2C_I2CONSET_AA; 00377 } 00378 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00379 break; 00380 00381 /* Data has been received, ACK has been returned ----------------------*/ 00382 case I2C_I2STAT_M_RX_DAT_ACK: 00383 // Note save data and increase counter first, then check later 00384 /* Save data */ 00385 if ((txrx_setup->rx_data != NULL) && (txrx_setup->rx_count < txrx_setup->rx_length)){ 00386 *(uint8_t *)(txrx_setup->rx_data + txrx_setup->rx_count) = (I2Cx->I2DAT & I2C_I2DAT_BITMASK); 00387 txrx_setup->rx_count++; 00388 } 00389 if (txrx_setup->rx_count < (txrx_setup->rx_length - 1)) { 00390 /*Data will be received, ACK will be return*/ 00391 I2Cx->I2CONSET = I2C_I2CONSET_AA; 00392 } 00393 else { 00394 /*Last data will be received, NACK will be return*/ 00395 I2Cx->I2CONCLR = I2C_I2CONSET_AA; 00396 } 00397 00398 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00399 break; 00400 00401 /* Data has been received, NACK has been return -------------------------*/ 00402 case I2C_I2STAT_M_RX_DAT_NACK: 00403 /* Save the last data */ 00404 if ((txrx_setup->rx_data != NULL) && (txrx_setup->rx_count < txrx_setup->rx_length)){ 00405 *(uint8_t *)(txrx_setup->rx_data + txrx_setup->rx_count) = (I2Cx->I2DAT & I2C_I2DAT_BITMASK); 00406 txrx_setup->rx_count++; 00407 } 00408 // success, go to end stage 00409 txrx_setup->status |= I2C_SETUP_STATUS_DONE; 00410 goto end_stage; 00411 00412 /* SLA+R has been transmitted, NACK has been received ------------------*/ 00413 case I2C_I2STAT_M_RX_SLAR_NACK: 00414 // update status 00415 txrx_setup->status |= I2C_SETUP_STATUS_NOACKF; 00416 goto retry; 00417 00418 /* Arbitration lost ----------------------------------------------------*/ 00419 case I2C_I2STAT_M_RX_ARB_LOST: 00420 // update status 00421 txrx_setup->status |= I2C_SETUP_STATUS_ARBF; 00422 default: 00423 retry: 00424 // check if retransmission is available 00425 if (txrx_setup->retransmissions_count < txrx_setup->retransmissions_max){ 00426 // Clear tx count 00427 txrx_setup->tx_count = 0; 00428 I2Cx->I2CONSET = I2C_I2CONSET_STA; 00429 I2Cx->I2CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC; 00430 txrx_setup->retransmissions_count++; 00431 } 00432 // End of stage 00433 else { 00434 end_stage: 00435 // Disable interrupt 00436 I2C_IntCmd(I2Cx, DISABLE); 00437 // Send stop 00438 I2C_Stop(I2Cx); 00439 // Call callback if installed 00440 if (txrx_setup->callback != NULL){ 00441 txrx_setup->callback(); 00442 } 00443 } 00444 break; 00445 } 00446 } 00447 } 00448 00449 00450 /*********************************************************************//** 00451 * @brief General Slave Interrupt handler for I2C peripheral 00452 * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2 00453 * @return None 00454 **********************************************************************/ 00455 void I2C_SlaveHandler (LPC_I2C_TypeDef *I2Cx) 00456 { 00457 int32_t tmp; 00458 uint8_t returnCode; 00459 I2C_S_SETUP_Type *txrx_setup; 00460 uint32_t timeout; 00461 00462 tmp = I2C_getNum(I2Cx); 00463 txrx_setup = (I2C_S_SETUP_Type *) i2cdat[tmp].txrx_setup; 00464 00465 returnCode = (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK); 00466 // Save current status 00467 txrx_setup->status = returnCode; 00468 // there's no relevant information 00469 if (returnCode == I2C_I2STAT_NO_INF){ 00470 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00471 return; 00472 } 00473 00474 00475 switch (returnCode) 00476 { 00477 00478 /* No status information */ 00479 case I2C_I2STAT_NO_INF: 00480 I2Cx->I2CONSET = I2C_I2CONSET_AA; 00481 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00482 break; 00483 00484 /* Reading phase -------------------------------------------------------- */ 00485 /* Own SLA+R has been received, ACK has been returned */ 00486 case I2C_I2STAT_S_RX_SLAW_ACK: 00487 /* General call address has been received, ACK has been returned */ 00488 case I2C_I2STAT_S_RX_GENCALL_ACK: 00489 I2Cx->I2CONSET = I2C_I2CONSET_AA; 00490 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00491 break; 00492 00493 /* Previously addressed with own SLA; 00494 * DATA byte has been received; 00495 * ACK has been returned */ 00496 case I2C_I2STAT_S_RX_PRE_SLA_DAT_ACK: 00497 /* DATA has been received, ACK hasn been return */ 00498 case I2C_I2STAT_S_RX_PRE_GENCALL_DAT_ACK: 00499 /* 00500 * All data bytes that over-flow the specified receive 00501 * data length, just ignore them. 00502 */ 00503 if ((txrx_setup->rx_count < txrx_setup->rx_length) \ 00504 && (txrx_setup->rx_data != NULL)){ 00505 *(uint8_t *)(txrx_setup->rx_data + txrx_setup->rx_count) = (uint8_t)I2Cx->I2DAT; 00506 txrx_setup->rx_count++; 00507 } 00508 I2Cx->I2CONSET = I2C_I2CONSET_AA; 00509 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00510 break; 00511 00512 /* Previously addressed with own SLA; 00513 * DATA byte has been received; 00514 * NOT ACK has been returned */ 00515 case I2C_I2STAT_S_RX_PRE_SLA_DAT_NACK: 00516 /* DATA has been received, NOT ACK has been returned */ 00517 case I2C_I2STAT_S_RX_PRE_GENCALL_DAT_NACK: 00518 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00519 break; 00520 00521 /* 00522 * Note that: Return code only let us know a stop condition mixed 00523 * with a repeat start condition in the same code value. 00524 * So we should provide a time-out. In case this is really a stop 00525 * condition, this will return back after time out condition. Otherwise, 00526 * next session that is slave receive data will be completed. 00527 */ 00528 00529 /* A Stop or a repeat start condition */ 00530 case I2C_I2STAT_S_RX_STA_STO_SLVREC_SLVTRX: 00531 // Temporally lock the interrupt for timeout condition 00532 I2C_IntCmd(I2Cx, DISABLE); 00533 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00534 // enable time out 00535 timeout = I2C_SLAVE_TIME_OUT; 00536 while(1){ 00537 if (I2Cx->I2CONSET & I2C_I2CONSET_SI){ 00538 // re-Enable interrupt 00539 I2C_IntCmd(I2Cx, ENABLE); 00540 break; 00541 } else { 00542 timeout--; 00543 if (timeout == 0){ 00544 // timeout occur, it's really a stop condition 00545 txrx_setup->status |= I2C_SETUP_STATUS_DONE; 00546 goto s_int_end; 00547 } 00548 } 00549 } 00550 break; 00551 00552 /* Writing phase -------------------------------------------------------- */ 00553 /* Own SLA+R has been received, ACK has been returned */ 00554 case I2C_I2STAT_S_TX_SLAR_ACK: 00555 /* Data has been transmitted, ACK has been received */ 00556 case I2C_I2STAT_S_TX_DAT_ACK: 00557 /* 00558 * All data bytes that over-flow the specified receive 00559 * data length, just ignore them. 00560 */ 00561 if ((txrx_setup->tx_count < txrx_setup->tx_length) \ 00562 && (txrx_setup->tx_data != NULL)){ 00563 I2Cx->I2DAT = *(uint8_t *) (txrx_setup->tx_data + txrx_setup->tx_count); 00564 txrx_setup->tx_count++; 00565 } 00566 I2Cx->I2CONSET = I2C_I2CONSET_AA; 00567 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00568 break; 00569 00570 /* Data has been transmitted, NACK has been received, 00571 * that means there's no more data to send, exit now */ 00572 /* 00573 * Note: Don't wait for stop event since in slave transmit mode, 00574 * since there no proof lets us know when a stop signal has been received 00575 * on slave side. 00576 */ 00577 case I2C_I2STAT_S_TX_DAT_NACK: 00578 I2Cx->I2CONSET = I2C_I2CONSET_AA; 00579 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00580 txrx_setup->status |= I2C_SETUP_STATUS_DONE; 00581 goto s_int_end; 00582 00583 // Other status must be captured 00584 default: 00585 s_int_end: 00586 // Disable interrupt 00587 I2C_IntCmd(I2Cx, DISABLE); 00588 I2Cx->I2CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC; 00589 // Call callback if installed 00590 if (txrx_setup->callback != NULL){ 00591 txrx_setup->callback(); 00592 } 00593 break; 00594 } 00595 } 00596 00597 /** 00598 * @} 00599 */ 00600 00601 00602 /* Public Functions ----------------------------------------------------------- */ 00603 /** @addtogroup I2C_Public_Functions 00604 * @{ 00605 */ 00606 00607 /*********************************************************************//** 00608 * @brief Setup clock rate for I2C peripheral 00609 * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2 00610 * @param[in] target_clock : clock of SSP (Hz) 00611 * @return None 00612 ***********************************************************************/ 00613 void I2C_SetClock (LPC_I2C_TypeDef *I2Cx, uint32_t target_clock) 00614 { 00615 uint32_t temp=0; 00616 00617 CHECK_PARAM(PARAM_I2Cx(I2Cx)); 00618 00619 // Get PCLK of I2C controller 00620 if (I2Cx == LPC_I2C0) 00621 { 00622 temp = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_I2C0) / target_clock; 00623 } 00624 else if (I2Cx == LPC_I2C1) 00625 { 00626 temp = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_I2C1) / target_clock; 00627 } 00628 else if (I2Cx == LPC_I2C2) 00629 { 00630 temp = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_I2C1) / target_clock; 00631 } 00632 00633 /* Set the I2C clock value to register */ 00634 I2Cx->I2SCLH = (uint32_t)(temp / 2); 00635 I2Cx->I2SCLL = (uint32_t)(temp - I2Cx->I2SCLH); 00636 } 00637 00638 00639 /*********************************************************************//** 00640 * @brief De-initializes the I2C peripheral registers to their 00641 * default reset values. 00642 * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2 00643 * @return None 00644 **********************************************************************/ 00645 void I2C_DeInit(LPC_I2C_TypeDef* I2Cx) 00646 { 00647 CHECK_PARAM(PARAM_I2Cx(I2Cx)); 00648 00649 /* Disable I2C control */ 00650 I2Cx->I2CONCLR = I2C_I2CONCLR_I2ENC; 00651 00652 if (I2Cx==LPC_I2C0) 00653 { 00654 /* Disable power for I2C0 module */ 00655 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C0, DISABLE); 00656 } 00657 else if (I2Cx==LPC_I2C1) 00658 { 00659 /* Disable power for I2C1 module */ 00660 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C1, DISABLE); 00661 } 00662 else if (I2Cx==LPC_I2C2) 00663 { 00664 /* Disable power for I2C2 module */ 00665 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C2, DISABLE); 00666 } 00667 } 00668 00669 00670 /********************************************************************//** 00671 * @brief Initializes the I2Cx peripheral with specified parameter. 00672 * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2 00673 * @param[in] clockrate Target clock rate value to initialized I2C 00674 * peripheral 00675 * @return None 00676 *********************************************************************/ 00677 void I2C_Init(LPC_I2C_TypeDef *I2Cx, uint32_t clockrate) 00678 { 00679 CHECK_PARAM(PARAM_I2Cx(I2Cx)); 00680 00681 if (I2Cx==LPC_I2C0) 00682 { 00683 /* Set up clock and power for I2C0 module */ 00684 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C0, ENABLE); 00685 /* As default, peripheral clock for I2C0 module 00686 * is set to FCCLK / 2 */ 00687 CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_I2C0, CLKPWR_PCLKSEL_CCLK_DIV_2); 00688 } 00689 else if (I2Cx==LPC_I2C1) 00690 { 00691 /* Set up clock and power for I2C1 module */ 00692 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C1, ENABLE); 00693 /* As default, peripheral clock for I2C1 module 00694 * is set to FCCLK / 2 */ 00695 CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_I2C1, CLKPWR_PCLKSEL_CCLK_DIV_2); 00696 } 00697 else if (I2Cx==LPC_I2C2) 00698 { 00699 /* Set up clock and power for I2C2 module */ 00700 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C2, ENABLE); 00701 /* As default, peripheral clock for I2C2 module 00702 * is set to FCCLK / 2 */ 00703 CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_I2C2, CLKPWR_PCLKSEL_CCLK_DIV_2); 00704 } 00705 else { 00706 // Up-Support this device 00707 return; 00708 } 00709 00710 /* Set clock rate */ 00711 I2C_SetClock(I2Cx, clockrate); 00712 /* Set I2C operation to default */ 00713 I2Cx->I2CONCLR = (I2C_I2CONCLR_AAC | I2C_I2CONCLR_STAC | I2C_I2CONCLR_I2ENC); 00714 } 00715 00716 00717 /*********************************************************************//** 00718 * @brief Enable or disable I2C peripheral's operation 00719 * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2 00720 * @param[in] NewState New State of I2Cx peripheral's operation 00721 * @return none 00722 **********************************************************************/ 00723 void I2C_Cmd(LPC_I2C_TypeDef* I2Cx, FunctionalState NewState) 00724 { 00725 CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); 00726 CHECK_PARAM(PARAM_I2Cx(I2Cx)); 00727 00728 if (NewState == ENABLE) 00729 { 00730 I2Cx->I2CONSET = I2C_I2CONSET_I2EN; 00731 } 00732 else 00733 { 00734 I2Cx->I2CONCLR = I2C_I2CONCLR_I2ENC; 00735 } 00736 } 00737 00738 00739 /*********************************************************************//** 00740 * @brief Transmit and Receive data in master mode 00741 * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2 00742 * @param[in] TransferCfg Pointer to a I2C_M_SETUP_Type structure that 00743 * contains specified information about the 00744 * configuration for master transfer. 00745 * @param[in] Opt a I2C_TRANSFER_OPT_Type type that selected for 00746 * interrupt or polling mode. 00747 * @return SUCCESS or ERROR 00748 * 00749 * Note: 00750 * - In case of using I2C to transmit data only, either transmit length set to 0 00751 * or transmit data pointer set to NULL. 00752 * - In case of using I2C to receive data only, either receive length set to 0 00753 * or receive data pointer set to NULL. 00754 * - In case of using I2C to transmit followed by receive data, transmit length, 00755 * transmit data pointer, receive length and receive data pointer should be set 00756 * corresponding. 00757 **********************************************************************/ 00758 Status I2C_MasterTransferData(LPC_I2C_TypeDef *I2Cx, I2C_M_SETUP_Type *TransferCfg, \ 00759 I2C_TRANSFER_OPT_Type Opt) 00760 { 00761 uint8_t *txdat; 00762 uint8_t *rxdat; 00763 uint32_t CodeStatus=0; 00764 uint8_t tmp=0; 00765 00766 // reset all default state 00767 txdat = (uint8_t *) TransferCfg->tx_data; 00768 rxdat = (uint8_t *) TransferCfg->rx_data; 00769 // Reset I2C setup value to default state 00770 TransferCfg->tx_count = 0; 00771 TransferCfg->rx_count = 0; 00772 TransferCfg->status = 0; 00773 00774 if (Opt == I2C_TRANSFER_POLLING){ 00775 00776 /* First Start condition -------------------------------------------------------------- */ 00777 TransferCfg->retransmissions_count = 0; 00778 retry: 00779 // reset all default state 00780 txdat = (uint8_t *) TransferCfg->tx_data; 00781 rxdat = (uint8_t *) TransferCfg->rx_data; 00782 // Reset I2C setup value to default state 00783 TransferCfg->tx_count = 0; 00784 TransferCfg->rx_count = 0; 00785 CodeStatus = 0; 00786 00787 // Start command 00788 CodeStatus = I2C_Start(I2Cx); 00789 if ((CodeStatus != I2C_I2STAT_M_TX_START) \ 00790 && (CodeStatus != I2C_I2STAT_M_TX_RESTART)){ 00791 TransferCfg->retransmissions_count++; 00792 if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ 00793 // save status 00794 TransferCfg->status = CodeStatus; 00795 goto error; 00796 } else { 00797 goto retry; 00798 } 00799 } 00800 00801 /* In case of sending data first --------------------------------------------------- */ 00802 if ((TransferCfg->tx_length != 0) && (TransferCfg->tx_data != NULL)){ 00803 00804 /* Send slave address + WR direction bit = 0 ----------------------------------- */ 00805 CodeStatus = I2C_SendByte(I2Cx, (TransferCfg->sl_addr7bit << 1)); 00806 if (CodeStatus != I2C_I2STAT_M_TX_SLAW_ACK){ 00807 TransferCfg->retransmissions_count++; 00808 if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ 00809 // save status 00810 TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_NOACKF; 00811 goto error; 00812 } else { 00813 goto retry; 00814 } 00815 } 00816 00817 /* Send a number of data bytes ---------------------------------------- */ 00818 while (TransferCfg->tx_count < TransferCfg->tx_length) 00819 { 00820 CodeStatus = I2C_SendByte(I2Cx, *txdat); 00821 if (CodeStatus != I2C_I2STAT_M_TX_DAT_ACK){ 00822 TransferCfg->retransmissions_count++; 00823 if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ 00824 // save status 00825 TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_NOACKF; 00826 goto error; 00827 } else { 00828 goto retry; 00829 } 00830 } 00831 00832 txdat++; 00833 TransferCfg->tx_count++; 00834 } 00835 } 00836 00837 /* Second Start condition (Repeat Start) ------------------------------------------- */ 00838 if ((TransferCfg->tx_length != 0) && (TransferCfg->tx_data != NULL) \ 00839 && (TransferCfg->rx_length != 0) && (TransferCfg->rx_data != NULL)){ 00840 00841 CodeStatus = I2C_Start(I2Cx); 00842 if ((CodeStatus != I2C_I2STAT_M_RX_START) \ 00843 && (CodeStatus != I2C_I2STAT_M_RX_RESTART)){ 00844 TransferCfg->retransmissions_count++; 00845 if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ 00846 // Update status 00847 TransferCfg->status = CodeStatus; 00848 goto error; 00849 } else { 00850 goto retry; 00851 } 00852 } 00853 } 00854 00855 /* Then, start reading after sending data -------------------------------------- */ 00856 if ((TransferCfg->rx_length != 0) && (TransferCfg->rx_data != NULL)){ 00857 /* Send slave address + RD direction bit = 1 ----------------------------------- */ 00858 00859 CodeStatus = I2C_SendByte(I2Cx, ((TransferCfg->sl_addr7bit << 1) | 0x01)); 00860 if (CodeStatus != I2C_I2STAT_M_RX_SLAR_ACK){ 00861 TransferCfg->retransmissions_count++; 00862 if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ 00863 // update status 00864 TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_NOACKF; 00865 goto error; 00866 } else { 00867 goto retry; 00868 } 00869 } 00870 00871 /* Receive a number of data bytes ------------------------------------------------- */ 00872 while (TransferCfg->rx_count < TransferCfg->rx_length){ 00873 00874 /* 00875 * Note that: if data length is only one, the master should not 00876 * issue an ACK signal on bus after reading to avoid of next data frame 00877 * on slave side 00878 */ 00879 if (TransferCfg->rx_count < (TransferCfg->rx_length - 1)){ 00880 // Issue an ACK signal for next data frame 00881 CodeStatus = I2C_GetByte(I2Cx, &tmp, TRUE); 00882 if (CodeStatus != I2C_I2STAT_M_RX_DAT_ACK){ 00883 TransferCfg->retransmissions_count++; 00884 if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ 00885 // update status 00886 TransferCfg->status = CodeStatus; 00887 goto error; 00888 } else { 00889 goto retry; 00890 } 00891 } 00892 } else { 00893 // Do not issue an ACK signal 00894 CodeStatus = I2C_GetByte(I2Cx, &tmp, FALSE); 00895 if (CodeStatus != I2C_I2STAT_M_RX_DAT_NACK){ 00896 TransferCfg->retransmissions_count++; 00897 if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ 00898 // update status 00899 TransferCfg->status = CodeStatus; 00900 goto error; 00901 } else { 00902 goto retry; 00903 } 00904 } 00905 } 00906 *rxdat++ = tmp; 00907 TransferCfg->rx_count++; 00908 } 00909 } 00910 00911 /* Send STOP condition ------------------------------------------------- */ 00912 I2C_Stop(I2Cx); 00913 return SUCCESS; 00914 00915 error: 00916 // Send stop condition 00917 I2C_Stop(I2Cx); 00918 return ERROR; 00919 } 00920 00921 else if (Opt == I2C_TRANSFER_INTERRUPT){ 00922 // Setup tx_rx data, callback and interrupt handler 00923 tmp = I2C_getNum(I2Cx); 00924 i2cdat[tmp].txrx_setup = (uint32_t) TransferCfg; 00925 i2cdat[tmp].inthandler = I2C_MasterHandler; 00926 // Set direction phase, write first 00927 i2cdat[tmp].dir = 0; 00928 00929 /* First Start condition -------------------------------------------------------------- */ 00930 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00931 I2Cx->I2CONSET = I2C_I2CONSET_STA; 00932 I2C_IntCmd(I2Cx, ENABLE); 00933 00934 return (SUCCESS); 00935 } 00936 00937 return ERROR; 00938 } 00939 00940 /*********************************************************************//** 00941 * @brief Receive and Transmit data in slave mode 00942 * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2 00943 * @param[in] TransferCfg Pointer to a I2C_S_SETUP_Type structure that 00944 * contains specified information about the 00945 * configuration for master transfer. 00946 * @param[in] Opt I2C_TRANSFER_OPT_Type type that selected for 00947 * interrupt or polling mode. 00948 * @return SUCCESS or ERROR 00949 * 00950 * Note: 00951 * The mode of slave's operation depends on the command sent from master on 00952 * the I2C bus. If the master send a SLA+W command, this sub-routine will 00953 * use receive data length and receive data pointer. If the master send a SLA+R 00954 * command, this sub-routine will use transmit data length and transmit data 00955 * pointer. 00956 * If the master issue an repeat start command or a stop command, the slave will 00957 * enable an time out condition, during time out condition, if there's no activity 00958 * on I2C bus, the slave will exit, otherwise (i.e. the master send a SLA+R/W), 00959 * the slave then switch to relevant operation mode. The time out should be used 00960 * because the return status code can not show difference from stop and repeat 00961 * start command in slave operation. 00962 * In case of the expected data length from master is greater than data length 00963 * that slave can support: 00964 * - In case of reading operation (from master): slave will return I2C_I2DAT_IDLE_CHAR 00965 * value. 00966 * - In case of writing operation (from master): slave will ignore remain data from master. 00967 **********************************************************************/ 00968 Status I2C_SlaveTransferData(LPC_I2C_TypeDef *I2Cx, I2C_S_SETUP_Type *TransferCfg, \ 00969 I2C_TRANSFER_OPT_Type Opt) 00970 { 00971 uint8_t *txdat; 00972 uint8_t *rxdat; 00973 uint32_t CodeStatus=0; 00974 uint32_t timeout; 00975 int32_t time_en; 00976 int32_t tmp; 00977 00978 // reset all default state 00979 txdat = (uint8_t *) TransferCfg->tx_data; 00980 rxdat = (uint8_t *) TransferCfg->rx_data; 00981 // Reset I2C setup value to default state 00982 TransferCfg->tx_count = 0; 00983 TransferCfg->rx_count = 0; 00984 TransferCfg->status = 0; 00985 00986 00987 // Polling option 00988 if (Opt == I2C_TRANSFER_POLLING){ 00989 00990 /* Set AA bit to ACK command on I2C bus */ 00991 I2Cx->I2CONSET = I2C_I2CONSET_AA; 00992 /* Clear SI bit to be ready ... */ 00993 I2Cx->I2CONCLR = (I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC); 00994 00995 time_en = 0; 00996 timeout = 0; 00997 00998 while (1) 00999 { 01000 /* Check SI flag ready */ 01001 if (I2Cx->I2CONSET & I2C_I2CONSET_SI) 01002 { 01003 time_en = 0; 01004 01005 switch (CodeStatus = (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK)) 01006 { 01007 01008 /* No status information */ 01009 case I2C_I2STAT_NO_INF: 01010 I2Cx->I2CONSET = I2C_I2CONSET_AA; 01011 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 01012 break; 01013 01014 /* Reading phase -------------------------------------------------------- */ 01015 /* Own SLA+R has been received, ACK has been returned */ 01016 case I2C_I2STAT_S_RX_SLAW_ACK: 01017 /* General call address has been received, ACK has been returned */ 01018 case I2C_I2STAT_S_RX_GENCALL_ACK: 01019 I2Cx->I2CONSET = I2C_I2CONSET_AA; 01020 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 01021 break; 01022 01023 /* Previously addressed with own SLA; 01024 * DATA byte has been received; 01025 * ACK has been returned */ 01026 case I2C_I2STAT_S_RX_PRE_SLA_DAT_ACK: 01027 /* DATA has been received, ACK hasn been return */ 01028 case I2C_I2STAT_S_RX_PRE_GENCALL_DAT_ACK: 01029 /* 01030 * All data bytes that over-flow the specified receive 01031 * data length, just ignore them. 01032 */ 01033 if ((TransferCfg->rx_count < TransferCfg->rx_length) \ 01034 && (TransferCfg->rx_data != NULL)){ 01035 *rxdat++ = (uint8_t)I2Cx->I2DAT; 01036 TransferCfg->rx_count++; 01037 } 01038 I2Cx->I2CONSET = I2C_I2CONSET_AA; 01039 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 01040 break; 01041 01042 /* Previously addressed with own SLA; 01043 * DATA byte has been received; 01044 * NOT ACK has been returned */ 01045 case I2C_I2STAT_S_RX_PRE_SLA_DAT_NACK: 01046 /* DATA has been received, NOT ACK has been returned */ 01047 case I2C_I2STAT_S_RX_PRE_GENCALL_DAT_NACK: 01048 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 01049 break; 01050 01051 /* 01052 * Note that: Return code only let us know a stop condition mixed 01053 * with a repeat start condition in the same code value. 01054 * So we should provide a time-out. In case this is really a stop 01055 * condition, this will return back after time out condition. Otherwise, 01056 * next session that is slave receive data will be completed. 01057 */ 01058 01059 /* A Stop or a repeat start condition */ 01060 case I2C_I2STAT_S_RX_STA_STO_SLVREC_SLVTRX: 01061 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 01062 // enable time out 01063 time_en = 1; 01064 timeout = 0; 01065 break; 01066 01067 /* Writing phase -------------------------------------------------------- */ 01068 /* Own SLA+R has been received, ACK has been returned */ 01069 case I2C_I2STAT_S_TX_SLAR_ACK: 01070 /* Data has been transmitted, ACK has been received */ 01071 case I2C_I2STAT_S_TX_DAT_ACK: 01072 /* 01073 * All data bytes that over-flow the specified receive 01074 * data length, just ignore them. 01075 */ 01076 if ((TransferCfg->tx_count < TransferCfg->tx_length) \ 01077 && (TransferCfg->tx_data != NULL)){ 01078 I2Cx->I2DAT = *txdat++; 01079 TransferCfg->tx_count++; 01080 } 01081 I2Cx->I2CONSET = I2C_I2CONSET_AA; 01082 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 01083 break; 01084 01085 /* Data has been transmitted, NACK has been received, 01086 * that means there's no more data to send, exit now */ 01087 /* 01088 * Note: Don't wait for stop event since in slave transmit mode, 01089 * since there no proof lets us know when a stop signal has been received 01090 * on slave side. 01091 */ 01092 case I2C_I2STAT_S_TX_DAT_NACK: 01093 I2Cx->I2CONSET = I2C_I2CONSET_AA; 01094 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 01095 // enable time out 01096 time_en = 1; 01097 timeout = 0; 01098 break; 01099 01100 // Other status must be captured 01101 default: 01102 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 01103 goto s_error; 01104 } 01105 } else if (time_en){ 01106 if (timeout++ > I2C_SLAVE_TIME_OUT){ 01107 // it's really a stop condition, goto end stage 01108 goto s_end_stage; 01109 } 01110 } 01111 } 01112 01113 s_end_stage: 01114 /* Clear AA bit to disable ACK on I2C bus */ 01115 I2Cx->I2CONCLR = I2C_I2CONCLR_AAC; 01116 // Check if there's no error during operation 01117 // Update status 01118 TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_DONE; 01119 return SUCCESS; 01120 01121 s_error: 01122 /* Clear AA bit to disable ACK on I2C bus */ 01123 I2Cx->I2CONCLR = I2C_I2CONCLR_AAC; 01124 // Update status 01125 TransferCfg->status = CodeStatus; 01126 return ERROR; 01127 } 01128 01129 else if (Opt == I2C_TRANSFER_INTERRUPT){ 01130 // Setup tx_rx data, callback and interrupt handler 01131 tmp = I2C_getNum(I2Cx); 01132 i2cdat[tmp].txrx_setup = (uint32_t) TransferCfg; 01133 i2cdat[tmp].inthandler = I2C_SlaveHandler; 01134 // Set direction phase, read first 01135 i2cdat[tmp].dir = 1; 01136 01137 // Enable AA 01138 I2Cx->I2CONSET = I2C_I2CONSET_AA; 01139 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC; 01140 I2C_IntCmd(I2Cx, ENABLE); 01141 01142 return (SUCCESS); 01143 } 01144 01145 return ERROR; 01146 } 01147 01148 /*********************************************************************//** 01149 * @brief Set Own slave address in I2C peripheral corresponding to 01150 * parameter specified in OwnSlaveAddrConfigStruct. 01151 * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2 01152 * @param[in] OwnSlaveAddrConfigStruct Pointer to a I2C_OWNSLAVEADDR_CFG_Type 01153 * structure that contains the configuration information for the 01154 * specified I2C slave address. 01155 * @return None 01156 **********************************************************************/ 01157 void I2C_SetOwnSlaveAddr(LPC_I2C_TypeDef *I2Cx, I2C_OWNSLAVEADDR_CFG_Type *OwnSlaveAddrConfigStruct) 01158 { 01159 uint32_t tmp; 01160 CHECK_PARAM(PARAM_I2Cx(I2Cx)); 01161 CHECK_PARAM(PARAM_I2C_SLAVEADDR_CH(OwnSlaveAddrConfigStruct->SlaveAddrChannel)); 01162 CHECK_PARAM(PARAM_FUNCTIONALSTATE(OwnSlaveAddrConfigStruct->GeneralCallState)); 01163 01164 tmp = (((uint32_t)(OwnSlaveAddrConfigStruct->SlaveAddr_7bit << 1)) \ 01165 | ((OwnSlaveAddrConfigStruct->GeneralCallState == ENABLE) ? 0x01 : 0x00))& I2C_I2ADR_BITMASK; 01166 switch (OwnSlaveAddrConfigStruct->SlaveAddrChannel) 01167 { 01168 case 0: 01169 I2Cx->I2ADR0 = tmp; 01170 I2Cx->I2MASK0 = I2C_I2MASK_MASK((uint32_t) \ 01171 (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue)); 01172 break; 01173 case 1: 01174 I2Cx->I2ADR1 = tmp; 01175 I2Cx->I2MASK1 = I2C_I2MASK_MASK((uint32_t) \ 01176 (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue)); 01177 break; 01178 case 2: 01179 I2Cx->I2ADR2 = tmp; 01180 I2Cx->I2MASK2 = I2C_I2MASK_MASK((uint32_t) \ 01181 (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue)); 01182 break; 01183 case 3: 01184 I2Cx->I2ADR3 = tmp; 01185 I2Cx->I2MASK3 = I2C_I2MASK_MASK((uint32_t) \ 01186 (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue)); 01187 break; 01188 } 01189 } 01190 01191 01192 /*********************************************************************//** 01193 * @brief Configures functionality in I2C monitor mode 01194 * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2 01195 * @param[in] MonitorCfgType Monitor Configuration type, should be: 01196 * - I2C_MONITOR_CFG_SCL_OUTPUT: I2C module can 'stretch' 01197 * the clock line (hold it low) until it has had time to 01198 * respond to an I2C interrupt. 01199 * - I2C_MONITOR_CFG_MATCHALL: When this bit is set to '1' 01200 * and the I2C is in monitor mode, an interrupt will be 01201 * generated on ANY address received. 01202 * @param[in] NewState New State of this function, should be: 01203 * - ENABLE: Enable this function. 01204 * - DISABLE: Disable this function. 01205 * @return None 01206 **********************************************************************/ 01207 void I2C_MonitorModeConfig(LPC_I2C_TypeDef *I2Cx, uint32_t MonitorCfgType, FunctionalState NewState) 01208 { 01209 CHECK_PARAM(PARAM_I2Cx(I2Cx)); 01210 CHECK_PARAM(PARAM_I2C_MONITOR_CFG(MonitorCfgType)); 01211 CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); 01212 01213 if (NewState == ENABLE) 01214 { 01215 I2Cx->MMCTRL |= MonitorCfgType; 01216 } 01217 else 01218 { 01219 I2Cx->MMCTRL &= (~MonitorCfgType) & I2C_I2MMCTRL_BITMASK; 01220 } 01221 } 01222 01223 01224 /*********************************************************************//** 01225 * @brief Enable/Disable I2C monitor mode 01226 * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2 01227 * @param[in] NewState New State of this function, should be: 01228 * - ENABLE: Enable monitor mode. 01229 * - DISABLE: Disable monitor mode. 01230 * @return None 01231 **********************************************************************/ 01232 void I2C_MonitorModeCmd(LPC_I2C_TypeDef *I2Cx, FunctionalState NewState) 01233 { 01234 CHECK_PARAM(PARAM_I2Cx(I2Cx)); 01235 CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); 01236 01237 if (NewState == ENABLE) 01238 { 01239 I2Cx->MMCTRL |= I2C_I2MMCTRL_MM_ENA; 01240 } 01241 else 01242 { 01243 I2Cx->MMCTRL &= (~I2C_I2MMCTRL_MM_ENA) & I2C_I2MMCTRL_BITMASK; 01244 } 01245 } 01246 01247 01248 /*********************************************************************//** 01249 * @brief Get data from I2C data buffer in monitor mode. 01250 * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2 01251 * @return None 01252 * Note: In monitor mode, the I2C module may lose the ability to stretch 01253 * the clock (stall the bus) if the ENA_SCL bit is not set. This means that 01254 * the processor will have a limited amount of time to read the contents of 01255 * the data received on the bus. If the processor reads the I2DAT shift 01256 * register, as it ordinarily would, it could have only one bit-time to 01257 * respond to the interrupt before the received data is overwritten by 01258 * new data. 01259 **********************************************************************/ 01260 uint8_t I2C_MonitorGetDatabuffer(LPC_I2C_TypeDef *I2Cx) 01261 { 01262 CHECK_PARAM(PARAM_I2Cx(I2Cx)); 01263 return ((uint8_t)(I2Cx->I2DATA_BUFFER)); 01264 } 01265 01266 /*********************************************************************//** 01267 * @brief Standard Interrupt handler for I2C0 peripheral 01268 * @param[in] None 01269 * @return None 01270 **********************************************************************/ 01271 void I2C0_StdIntHandler(void) 01272 { 01273 i2cdat[0].inthandler(LPC_I2C0); 01274 } 01275 01276 /*********************************************************************//** 01277 * @brief Standard Interrupt handler for I2C1 peripheral 01278 * @param[in] None 01279 * @return None 01280 **********************************************************************/ 01281 void I2C1_StdIntHandler(void) 01282 { 01283 i2cdat[1].inthandler(LPC_I2C1); 01284 } 01285 01286 /*********************************************************************//** 01287 * @brief Standard Interrupt handler for I2C2 peripheral 01288 * @param[in] None 01289 * @return None 01290 **********************************************************************/ 01291 void I2C2_StdIntHandler(void) 01292 { 01293 i2cdat[2].inthandler(LPC_I2C2); 01294 } 01295 01296 01297 /** 01298 * @} 01299 */ 01300 01301 #endif /* _I2C */ 01302 01303 /** 01304 * @} 01305 */ 01306 01307 /* --------------------------------- End Of File ------------------------------ */
Generated on Tue Jul 12 2022 17:06:02 by 1.7.2