Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
00001 /* Includes ------------------------------------------------------------------- */ 00002 #include "mbed.h" 00003 #include "rtos.h" 00004 #include "lpc17xx_i2c.h" 00005 #include "lpc17xx_clkpwr.h" 00006 #include "lpc17xx_pinsel.h" 00007 00008 /* If this source file built with example, the LPC17xx FW library configuration 00009 * file in each example directory ("lpc17xx_libcfg.h") must be included, 00010 * otherwise the default FW library configuration file must be included instead 00011 */ 00012 00013 #ifdef __BUILD_WITH_EXAMPLE__ 00014 #include "lpc17xx_libcfg.h" 00015 #else 00016 #include "lpc17xx_libcfg_default.h" 00017 #endif /* __BUILD_WITH_EXAMPLE__ */ 00018 00019 00020 #ifdef _I2C 00021 00022 00023 00024 DigitalOut myled1(LED1); 00025 DigitalOut myled2(LED2); 00026 DigitalOut myled3(LED3); 00027 DigitalOut myled4(LED4); 00028 00029 Serial pc(USBTX, USBRX); // tx, rx 00030 00031 00032 void blinky(void const *args) 00033 { 00034 while(1){ 00035 myled1 = 1; 00036 Thread::wait(100); //wait(.1); 00037 myled1 = 0; 00038 00039 myled2 = 1; 00040 Thread::wait(100); //wait(.1); 00041 myled2 = 0; 00042 00043 myled3 = 1; 00044 Thread::wait(100); //wait(.1); 00045 myled3 = 0; 00046 00047 myled4 = 1; 00048 Thread::wait(100); //wait(.1); 00049 myled4 = 0; 00050 00051 myled3 = 1; 00052 Thread::wait(100); //wait(.1); 00053 myled3 = 0; 00054 00055 myled2 = 1; 00056 wait(.1); 00057 myled2 = 0; 00058 } 00059 } 00060 00061 00062 00063 00064 /* Private Types -------------------------------------------------------------- */ 00065 /** @defgroup I2C_Private_Types 00066 * @{ 00067 */ 00068 00069 /** 00070 * @brief I2C device configuration structure type 00071 */ 00072 typedef struct { 00073 uint32_t txrx_setup; /* Transmission setup */ 00074 int32_t dir; /* Current direction phase, 0 - write, 1 - read */ 00075 void (*inthandler)(LPC_I2C_TypeDef *I2Cx); /* Transmission interrupt handler */ 00076 } I2C_CFG_T; 00077 00078 /** 00079 * @} 00080 */ 00081 00082 /* Private Variables ---------------------------------------------------------- */ 00083 /** 00084 * @brief II2C driver data for I2C0, I2C1 and I2C2 00085 */ 00086 static I2C_CFG_T i2cdat[3]; 00087 00088 00089 00090 /* Private Functions ---------------------------------------------------------- */ 00091 /** @defgroup I2C_Private_Functions 00092 * @{ 00093 */ 00094 00095 /* Generate a start condition on I2C bus (in master mode only) */ 00096 static uint32_t I2C_Start (LPC_I2C_TypeDef *I2Cx); 00097 00098 /* Generate a stop condition on I2C bus (in master mode only) */ 00099 static void I2C_Stop (LPC_I2C_TypeDef *I2Cx); 00100 00101 /* I2C send byte subroutine */ 00102 static uint32_t I2C_SendByte (LPC_I2C_TypeDef *I2Cx, uint8_t databyte); 00103 00104 /* I2C get byte subroutine */ 00105 static uint32_t I2C_GetByte (LPC_I2C_TypeDef *I2Cx, uint8_t *retdat, Bool ack); 00106 00107 /* I2C interrupt master handler */ 00108 void I2C_MasterHandler (LPC_I2C_TypeDef *I2Cx); 00109 00110 /* I2C interrupt slave handler */ 00111 void I2C_SlaveHandler (LPC_I2C_TypeDef *I2Cx); 00112 00113 /* Enable interrupt for I2C device */ 00114 void I2C_IntCmd (LPC_I2C_TypeDef *I2Cx, Bool NewState); 00115 00116 /*--------------------------------------------------------------------------------*/ 00117 00118 /** 00119 * @brief Convert from I2C peripheral to number 00120 */ 00121 static int32_t I2C_getNum(LPC_I2C_TypeDef *I2Cx) 00122 { 00123 if (I2Cx == LPC_I2C0) { 00124 return (0); 00125 } else if (I2Cx == LPC_I2C1) { 00126 return (1); 00127 } else if (I2Cx == LPC_I2C2) { 00128 return (2); 00129 } 00130 return (-1); 00131 } 00132 00133 /*********************************************************************** 00134 * Function: I2C_Start 00135 * Purpose: Generate a start condition on I2C bus (in master mode only) 00136 * Parameters: 00137 * i2cdev: Pointer to I2C register 00138 * blocking: blocking or none blocking mode 00139 * Returns: value of I2C status register after generate a start condition 00140 **********************************************************************/ 00141 static uint32_t I2C_Start (LPC_I2C_TypeDef *I2Cx) 00142 { 00143 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00144 I2Cx->I2CONSET = I2C_I2CONSET_STA; 00145 00146 // Wait for complete 00147 while (!(I2Cx->I2CONSET & I2C_I2CONSET_SI)); 00148 I2Cx->I2CONCLR = I2C_I2CONCLR_STAC; 00149 return (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK); 00150 } 00151 00152 00153 /*********************************************************************** 00154 * Function: I2C_Stop 00155 * Purpose: Generate a stop condition on I2C bus (in master mode only) 00156 * Parameters: 00157 * I2Cx: Pointer to I2C register 00158 * Returns: None 00159 **********************************************************************/ 00160 static void I2C_Stop (LPC_I2C_TypeDef *I2Cx) 00161 { 00162 00163 /* Make sure start bit is not active */ 00164 if (I2Cx->I2CONSET & I2C_I2CONSET_STA) { 00165 I2Cx->I2CONCLR = I2C_I2CONCLR_STAC; 00166 } 00167 I2Cx->I2CONSET = I2C_I2CONSET_STO; 00168 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00169 } 00170 00171 00172 /*********************************************************************** 00173 * Function: I2C_SendByte 00174 * Purpose: Send a byte 00175 * Parameters: 00176 * I2Cx: Pointer to I2C register 00177 * Returns: value of I2C status register after sending 00178 **********************************************************************/ 00179 static uint32_t I2C_SendByte (LPC_I2C_TypeDef *I2Cx, uint8_t databyte) 00180 { 00181 /* Make sure start bit is not active */ 00182 if (I2Cx->I2CONSET & I2C_I2CONSET_STA) { 00183 I2Cx->I2CONCLR = I2C_I2CONCLR_STAC; 00184 } 00185 I2Cx->I2DAT = databyte & I2C_I2DAT_BITMASK; 00186 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00187 00188 while (!(I2Cx->I2CONSET & I2C_I2CONSET_SI)); 00189 return (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK); 00190 } 00191 00192 00193 /*********************************************************************** 00194 * Function: I2C_GetByte 00195 * Purpose: Get a byte 00196 * Parameters: 00197 * I2Cx: Pointer to I2C register 00198 * Returns: value of I2C status register after receiving 00199 **********************************************************************/ 00200 static uint32_t I2C_GetByte (LPC_I2C_TypeDef *I2Cx, uint8_t *retdat, Bool ack) 00201 { 00202 if (ack == TRUE) { 00203 I2Cx->I2CONSET = I2C_I2CONSET_AA; 00204 } else { 00205 I2Cx->I2CONCLR = I2C_I2CONCLR_AAC; 00206 } 00207 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00208 00209 while (!(I2Cx->I2CONSET & I2C_I2CONSET_SI)); 00210 *retdat = (uint8_t) (I2Cx->I2DAT & I2C_I2DAT_BITMASK); 00211 return (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK); 00212 } 00213 00214 00215 00216 /*********************************************************************//** 00217 * @brief Enable/Disable interrupt for I2C peripheral 00218 * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2 00219 * @param[in] NewState New State of I2C peripheral interrupt in NVIC core 00220 * should be: 00221 * - ENABLE: enable interrupt for this I2C peripheral 00222 * - DISABLE: disable interrupt for this I2C peripheral 00223 * @return None 00224 **********************************************************************/ 00225 void I2C_IntCmd (LPC_I2C_TypeDef *I2Cx, Bool NewState) 00226 { 00227 if (NewState) { 00228 if(I2Cx == LPC_I2C0) { 00229 NVIC_EnableIRQ(I2C0_IRQn); 00230 } else if (I2Cx == LPC_I2C1) { 00231 NVIC_EnableIRQ(I2C1_IRQn); 00232 } else if (I2Cx == LPC_I2C2) { 00233 NVIC_EnableIRQ(I2C2_IRQn); 00234 } 00235 } else { 00236 if(I2Cx == LPC_I2C0) { 00237 NVIC_DisableIRQ(I2C0_IRQn); 00238 } else if (I2Cx == LPC_I2C1) { 00239 NVIC_DisableIRQ(I2C1_IRQn); 00240 } else if (I2Cx == LPC_I2C2) { 00241 NVIC_DisableIRQ(I2C2_IRQn); 00242 } 00243 } 00244 return; 00245 } 00246 00247 00248 /*********************************************************************//** 00249 * @brief General Master Interrupt handler for I2C peripheral 00250 * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2 00251 * @return None 00252 **********************************************************************/ 00253 void I2C_MasterHandler (LPC_I2C_TypeDef *I2Cx) 00254 { 00255 int32_t tmp; 00256 uint8_t returnCode; 00257 I2C_M_SETUP_Type *txrx_setup; 00258 00259 tmp = I2C_getNum(I2Cx); 00260 txrx_setup = (I2C_M_SETUP_Type *) i2cdat[tmp].txrx_setup; 00261 00262 returnCode = (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK); 00263 // Save current status 00264 txrx_setup->status = returnCode; 00265 // there's no relevant information 00266 if (returnCode == I2C_I2STAT_NO_INF) { 00267 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00268 return; 00269 } 00270 00271 /* ----------------------------- TRANSMIT PHASE --------------------------*/ 00272 if (i2cdat[tmp].dir == 0) { 00273 switch (returnCode) { 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 } else { 00376 /*Last data will be received, NACK will be return*/ 00377 I2Cx->I2CONCLR = I2C_I2CONSET_AA; 00378 } 00379 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00380 break; 00381 00382 /* Data has been received, ACK has been returned ----------------------*/ 00383 case I2C_I2STAT_M_RX_DAT_ACK: 00384 // Note save data and increase counter first, then check later 00385 /* Save data */ 00386 if ((txrx_setup->rx_data != NULL) && (txrx_setup->rx_count < txrx_setup->rx_length)) { 00387 *(uint8_t *)(txrx_setup->rx_data + txrx_setup->rx_count) = (I2Cx->I2DAT & I2C_I2DAT_BITMASK); 00388 txrx_setup->rx_count++; 00389 } 00390 if (txrx_setup->rx_count < (txrx_setup->rx_length - 1)) { 00391 /*Data will be received, ACK will be return*/ 00392 I2Cx->I2CONSET = I2C_I2CONSET_AA; 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 //break; 00412 00413 /* SLA+R has been transmitted, NACK has been received ------------------*/ 00414 case I2C_I2STAT_M_RX_SLAR_NACK: 00415 // update status 00416 txrx_setup->status |= I2C_SETUP_STATUS_NOACKF; 00417 goto retry; 00418 //break; 00419 00420 /* Arbitration lost ----------------------------------------------------*/ 00421 case I2C_I2STAT_M_RX_ARB_LOST: 00422 // update status 00423 txrx_setup->status |= I2C_SETUP_STATUS_ARBF; 00424 default: 00425 retry: 00426 // check if retransmission is available 00427 if (txrx_setup->retransmissions_count < txrx_setup->retransmissions_max) { 00428 // Clear tx count 00429 txrx_setup->tx_count = 0; 00430 I2Cx->I2CONSET = I2C_I2CONSET_STA; 00431 I2Cx->I2CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC; 00432 txrx_setup->retransmissions_count++; 00433 } 00434 // End of stage 00435 else { 00436 end_stage: 00437 // Disable interrupt 00438 I2C_IntCmd(I2Cx, FALSE); 00439 // Send stop 00440 I2C_Stop(I2Cx); 00441 // Call callback if installed 00442 if (txrx_setup->callback != NULL) { 00443 txrx_setup->callback(); 00444 } 00445 } 00446 break; 00447 } 00448 } 00449 } 00450 00451 00452 /*********************************************************************//** 00453 * @brief General Slave Interrupt handler for I2C peripheral 00454 * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2 00455 * @return None 00456 **********************************************************************/ 00457 void I2C_SlaveHandler (LPC_I2C_TypeDef *I2Cx) 00458 { 00459 int32_t tmp =0; 00460 uint8_t returnCode; 00461 I2C_S_SETUP_Type *txrx_setup; 00462 uint32_t timeout; 00463 00464 pc.printf("INT\n\r"); 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 pc.printf("No Data!\n\r"); 00476 return; 00477 } 00478 00479 00480 switch (returnCode) { 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, FALSE); 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, TRUE); 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, FALSE); 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 00602 /** 00603 * @} 00604 */ 00605 00606 00607 /* Public Functions ----------------------------------------------------------- */ 00608 /** @addtogroup I2C_Public_Functions 00609 * @{ 00610 */ 00611 00612 /*********************************************************************//** 00613 * @brief Setup clock rate for I2C peripheral 00614 * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2 00615 * @param[in] target_clock : clock of SSP (Hz) 00616 * @return None 00617 ***********************************************************************/ 00618 void I2C_SetClock (LPC_I2C_TypeDef *I2Cx, uint32_t target_clock) // * @brief Setup clock rate for I2C peripheral 00619 { 00620 uint32_t temp=0; 00621 00622 if(target_clock <= 0) return; // guard ! don't div zero dummy ! ! 00623 // Get PCLK of I2C controller 00624 if (I2Cx == LPC_I2C0) { 00625 temp = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_I2C0) / target_clock; 00626 } else if (I2Cx == LPC_I2C1) { 00627 temp = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_I2C1) / target_clock; 00628 } else if (I2Cx == LPC_I2C2) { 00629 temp = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_I2C1) / target_clock; 00630 } 00631 00632 /* Set the I2C clock value to register */ 00633 I2Cx->I2SCLH = (uint32_t)(temp / 2); 00634 I2Cx->I2SCLL = (uint32_t)(temp - I2Cx->I2SCLH); 00635 } 00636 00637 00638 /*********************************************************************//** 00639 * @brief De-initializes the I2C peripheral registers to their 00640 * default reset values. 00641 * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2 00642 * @return None 00643 **********************************************************************/ 00644 void I2C_DeInit(LPC_I2C_TypeDef* I2Cx) 00645 { 00646 00647 /* Disable I2C control */ 00648 I2Cx->I2CONCLR = I2C_I2CONCLR_I2ENC; 00649 00650 if (I2Cx==LPC_I2C0) { 00651 /* Disable power for I2C0 module */ 00652 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C0, DISABLE); 00653 } else if (I2Cx==LPC_I2C1) { 00654 /* Disable power for I2C1 module */ 00655 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C1, DISABLE); 00656 } else if (I2Cx==LPC_I2C2) { 00657 /* Disable power for I2C2 module */ 00658 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C2, DISABLE); 00659 } 00660 } 00661 00662 00663 /********************************************************************//** 00664 * @brief Initializes the I2Cx peripheral with specified parameter. 00665 * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2 00666 * @param[in] clockrate Target clock rate value to initialized I2C 00667 * peripheral 00668 * @return None 00669 *********************************************************************/ 00670 void I2C_Init(LPC_I2C_TypeDef *I2Cx, uint32_t clockrate) 00671 { 00672 if (I2Cx==LPC_I2C0) { 00673 /* Set up clock and power for I2C0 module */ 00674 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C0, ENABLE); 00675 /* As default, peripheral clock for I2C0 module is set to FCCLK / 2 */ 00676 CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_I2C0, CLKPWR_PCLKSEL_CCLK_DIV_2); 00677 } else if (I2Cx==LPC_I2C1) { 00678 /* Set up clock and power for I2C1 module */ 00679 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C1, ENABLE); 00680 /* As default, peripheral clock for I2C1 module is set to FCCLK / 2 */ 00681 CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_I2C1, CLKPWR_PCLKSEL_CCLK_DIV_2); 00682 } else if (I2Cx==LPC_I2C2) { 00683 /* Set up clock and power for I2C2 module */ 00684 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C2, ENABLE); 00685 /* As default, peripheral clock for I2C2 module is set to FCCLK / 2 */ 00686 CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_I2C2, CLKPWR_PCLKSEL_CCLK_DIV_2); 00687 } else { 00688 // Up-Support this device 00689 return; 00690 } 00691 00692 /* Set clock rate */ 00693 I2C_SetClock(I2Cx, clockrate); 00694 /* Set I2C operation to default */ 00695 I2Cx->I2CONCLR = (I2C_I2CONCLR_AAC | I2C_I2CONCLR_STAC | I2C_I2CONCLR_I2ENC); 00696 } 00697 00698 00699 /*********************************************************************//** 00700 * @brief Enable or disable I2C peripheral's operation 00701 * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2 00702 * @param[in] NewState New State of I2Cx peripheral's operation 00703 * @return none 00704 **********************************************************************/ 00705 void I2C_Cmd(LPC_I2C_TypeDef* I2Cx, FunctionalState NewState) 00706 { 00707 00708 if (NewState == ENABLE) { 00709 I2Cx->I2CONSET = I2C_I2CONSET_I2EN; 00710 } else { 00711 I2Cx->I2CONCLR = I2C_I2CONCLR_I2ENC; 00712 } 00713 } 00714 00715 00716 /*********************************************************************//** 00717 * @brief Transmit and Receive data in master mode 00718 * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2 00719 * @param[in] TransferCfg Pointer to a I2C_M_SETUP_Type structure that 00720 * contains specified information about the 00721 * configuration for master transfer. 00722 * @param[in] Opt a I2C_TRANSFER_OPT_Type type that selected for 00723 * interrupt or polling mode. 00724 * @return SUCCESS or ERROR 00725 * 00726 * Note: 00727 * - In case of using I2C to transmit data only, either transmit length set to 0 00728 * or transmit data pointer set to NULL. 00729 * - In case of using I2C to receive data only, either receive length set to 0 00730 * or receive data pointer set to NULL. 00731 * - In case of using I2C to transmit followed by receive data, transmit length, 00732 * transmit data pointer, receive length and receive data pointer should be set 00733 * corresponding. 00734 **********************************************************************/ 00735 Status I2C_MasterTransferData(LPC_I2C_TypeDef *I2Cx, I2C_M_SETUP_Type *TransferCfg, I2C_TRANSFER_OPT_Type Opt) 00736 { 00737 uint8_t *txdat; 00738 uint8_t *rxdat; 00739 uint32_t CodeStatus; 00740 uint8_t tmp; 00741 00742 // reset all default state 00743 txdat = (uint8_t *) TransferCfg->tx_data; 00744 rxdat = (uint8_t *) TransferCfg->rx_data; 00745 // Reset I2C setup value to default state 00746 TransferCfg->tx_count = 0; 00747 TransferCfg->rx_count = 0; 00748 TransferCfg->status = 0; 00749 00750 if (Opt == I2C_TRANSFER_POLLING) { 00751 00752 /* First Start condition -------------------------------------------------------------- */ 00753 TransferCfg->retransmissions_count = 0; 00754 retry: 00755 // reset all default state 00756 txdat = (uint8_t *) TransferCfg->tx_data; 00757 rxdat = (uint8_t *) TransferCfg->rx_data; 00758 // Reset I2C setup value to default state 00759 TransferCfg->tx_count = 0; 00760 TransferCfg->rx_count = 0; 00761 CodeStatus = 0; 00762 00763 // Start command 00764 CodeStatus = I2C_Start(I2Cx); 00765 if ((CodeStatus != I2C_I2STAT_M_TX_START) \ 00766 && (CodeStatus != I2C_I2STAT_M_TX_RESTART)) { 00767 TransferCfg->retransmissions_count++; 00768 if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max) { 00769 // save status 00770 TransferCfg->status = CodeStatus; 00771 goto error; 00772 } else { 00773 goto retry; 00774 } 00775 } 00776 00777 /* In case of sending data first --------------------------------------------------- */ 00778 if ((TransferCfg->tx_length != 0) && (TransferCfg->tx_data != NULL)) { 00779 00780 /* Send slave address + WR direction bit = 0 ----------------------------------- */ 00781 CodeStatus = I2C_SendByte(I2Cx, (TransferCfg->sl_addr7bit << 1)); 00782 if (CodeStatus != I2C_I2STAT_M_TX_SLAW_ACK) { 00783 TransferCfg->retransmissions_count++; 00784 if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max) { 00785 // save status 00786 TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_NOACKF; 00787 goto error; 00788 } else { 00789 goto retry; 00790 } 00791 } 00792 00793 /* Send a number of data bytes ---------------------------------------- */ 00794 while (TransferCfg->tx_count < TransferCfg->tx_length) { 00795 CodeStatus = I2C_SendByte(I2Cx, *txdat); 00796 if (CodeStatus != I2C_I2STAT_M_TX_DAT_ACK) { 00797 TransferCfg->retransmissions_count++; 00798 if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max) { 00799 // save status 00800 TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_NOACKF; 00801 goto error; 00802 } else { 00803 goto retry; 00804 } 00805 } 00806 00807 txdat++; 00808 TransferCfg->tx_count++; 00809 } 00810 } 00811 00812 /* Second Start condition (Repeat Start) ------------------------------------------- */ 00813 if ((TransferCfg->tx_length != 0) && (TransferCfg->tx_data != NULL) \ 00814 && (TransferCfg->rx_length != 0) && (TransferCfg->rx_data != NULL)) { 00815 00816 CodeStatus = I2C_Start(I2Cx); 00817 if ((CodeStatus != I2C_I2STAT_M_RX_START) \ 00818 && (CodeStatus != I2C_I2STAT_M_RX_RESTART)) { 00819 TransferCfg->retransmissions_count++; 00820 if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max) { 00821 // Update status 00822 TransferCfg->status = CodeStatus; 00823 goto error; 00824 } else { 00825 goto retry; 00826 } 00827 } 00828 } 00829 00830 /* Then, start reading after sending data -------------------------------------- */ 00831 if ((TransferCfg->rx_length != 0) && (TransferCfg->rx_data != NULL)) { 00832 /* Send slave address + RD direction bit = 1 ----------------------------------- */ 00833 00834 CodeStatus = I2C_SendByte(I2Cx, ((TransferCfg->sl_addr7bit << 1) | 0x01)); 00835 if (CodeStatus != I2C_I2STAT_M_RX_SLAR_ACK) { 00836 TransferCfg->retransmissions_count++; 00837 if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max) { 00838 // update status 00839 TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_NOACKF; 00840 goto error; 00841 } else { 00842 goto retry; 00843 } 00844 } 00845 00846 /* Receive a number of data bytes ------------------------------------------------- */ 00847 while (TransferCfg->rx_count < TransferCfg->rx_length) { 00848 00849 /* 00850 * Note that: if data length is only one, the master should not 00851 * issue an ACK signal on bus after reading to avoid of next data frame 00852 * on slave side 00853 */ 00854 if (TransferCfg->rx_count < (TransferCfg->rx_length - 1)) { 00855 // Issue an ACK signal for next data frame 00856 CodeStatus = I2C_GetByte(I2Cx, &tmp, TRUE); 00857 if (CodeStatus != I2C_I2STAT_M_RX_DAT_ACK) { 00858 TransferCfg->retransmissions_count++; 00859 if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max) { 00860 // update status 00861 TransferCfg->status = CodeStatus; 00862 goto error; 00863 } else { 00864 goto retry; 00865 } 00866 } 00867 } else { 00868 // Do not issue an ACK signal 00869 CodeStatus = I2C_GetByte(I2Cx, &tmp, FALSE); 00870 if (CodeStatus != I2C_I2STAT_M_RX_DAT_NACK) { 00871 TransferCfg->retransmissions_count++; 00872 if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max) { 00873 // update status 00874 TransferCfg->status = CodeStatus; 00875 goto error; 00876 } else { 00877 goto retry; 00878 } 00879 } 00880 } 00881 *rxdat++ = tmp; 00882 TransferCfg->rx_count++; 00883 } 00884 } 00885 00886 /* Send STOP condition ------------------------------------------------- */ 00887 I2C_Stop(I2Cx); 00888 return SUCCESS; 00889 00890 error: 00891 // Send stop condition 00892 I2C_Stop(I2Cx); 00893 return ERROR; 00894 } 00895 00896 else if (Opt == I2C_TRANSFER_INTERRUPT) { 00897 // Setup tx_rx data, callback and interrupt handler 00898 tmp = I2C_getNum(I2Cx); 00899 i2cdat[tmp].txrx_setup = (uint32_t) TransferCfg; 00900 i2cdat[tmp].inthandler = I2C_MasterHandler; 00901 // Set direction phase, write first 00902 i2cdat[tmp].dir = 0; 00903 00904 /* First Start condition -------------------------------------------------------------- */ 00905 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00906 I2Cx->I2CONSET = I2C_I2CONSET_STA; 00907 I2C_IntCmd(I2Cx, TRUE); 00908 00909 return (SUCCESS); 00910 } 00911 00912 return ERROR; 00913 } 00914 00915 /*********************************************************************//** 00916 * @brief Receive and Transmit data in slave mode 00917 * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2 00918 * @param[in] TransferCfg Pointer to a I2C_S_SETUP_Type structure that 00919 * contains specified information about the 00920 * configuration for master transfer. 00921 * @param[in] Opt I2C_TRANSFER_OPT_Type type that selected for 00922 * interrupt or polling mode. 00923 * @return SUCCESS or ERROR 00924 * 00925 * Note: 00926 * The mode of slave's operation depends on the command sent from master on 00927 * the I2C bus. If the master send a SLA+W command, this sub-routine will 00928 * use receive data length and receive data pointer. If the master send a SLA+R 00929 * command, this sub-routine will use transmit data length and transmit data 00930 * pointer. 00931 * If the master issue an repeat start command or a stop command, the slave will 00932 * enable an time out condition, during time out condition, if there's no activity 00933 * on I2C bus, the slave will exit, otherwise (i.e. the master send a SLA+R/W), 00934 * the slave then switch to relevant operation mode. The time out should be used 00935 * because the return status code can not show difference from stop and repeat 00936 * start command in slave operation. 00937 * In case of the expected data length from master is greater than data length 00938 * that slave can support: 00939 * - In case of reading operation (from master): slave will return I2C_I2DAT_IDLE_CHAR 00940 * value. 00941 * - In case of writing operation (from master): slave will ignore remain data from master. 00942 **********************************************************************/ 00943 Status I2C_SlaveTransferData(LPC_I2C_TypeDef *I2Cx, I2C_S_SETUP_Type *TransferCfg, \ 00944 I2C_TRANSFER_OPT_Type Opt) 00945 { 00946 uint8_t *txdat; 00947 uint8_t *rxdat; 00948 uint32_t CodeStatus=0; 00949 uint32_t timeout; 00950 int32_t time_en; 00951 int32_t tmp; 00952 00953 // reset all default state 00954 txdat = (uint8_t *) TransferCfg->tx_data; 00955 rxdat = (uint8_t *) TransferCfg->rx_data; 00956 // Reset I2C setup value to default state 00957 TransferCfg->tx_count = 0; 00958 TransferCfg->rx_count = 0; 00959 TransferCfg->status = 0; 00960 00961 00962 // Polling option 00963 if (Opt == I2C_TRANSFER_POLLING) { 00964 00965 /* Set AA bit to ACK command on I2C bus */ 00966 I2Cx->I2CONSET = I2C_I2CONSET_AA; 00967 /* Clear SI bit to be ready ... */ 00968 I2Cx->I2CONCLR = (I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC); 00969 00970 time_en = 0; 00971 timeout = 0; 00972 00973 while (1) { 00974 /* Check SI flag ready */ 00975 if (I2Cx->I2CONSET & I2C_I2CONSET_SI) { 00976 time_en = 0; 00977 00978 switch (CodeStatus = (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK)) { 00979 00980 /* No status information */ 00981 case I2C_I2STAT_NO_INF: 00982 I2Cx->I2CONSET = I2C_I2CONSET_AA; 00983 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00984 break; 00985 00986 /* Reading phase -------------------------------------------------------- */ 00987 /* Own SLA+R has been received, ACK has been returned */ 00988 case I2C_I2STAT_S_RX_SLAW_ACK: 00989 /* General call address has been received, ACK has been returned */ 00990 case I2C_I2STAT_S_RX_GENCALL_ACK: 00991 I2Cx->I2CONSET = I2C_I2CONSET_AA; 00992 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 00993 break; 00994 00995 /* Previously addressed with own SLA; 00996 * DATA byte has been received; 00997 * ACK has been returned */ 00998 case I2C_I2STAT_S_RX_PRE_SLA_DAT_ACK: 00999 /* DATA has been received, ACK hasn been return */ 01000 case I2C_I2STAT_S_RX_PRE_GENCALL_DAT_ACK: 01001 /* 01002 * All data bytes that over-flow the specified receive 01003 * data length, just ignore them. 01004 */ 01005 if ((TransferCfg->rx_count < TransferCfg->rx_length) \ 01006 && (TransferCfg->rx_data != NULL)) { 01007 *rxdat++ = (uint8_t)I2Cx->I2DAT; 01008 TransferCfg->rx_count++; 01009 } 01010 I2Cx->I2CONSET = I2C_I2CONSET_AA; 01011 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 01012 break; 01013 01014 /* Previously addressed with own SLA; 01015 * DATA byte has been received; 01016 * NOT ACK has been returned */ 01017 case I2C_I2STAT_S_RX_PRE_SLA_DAT_NACK: 01018 /* DATA has been received, NOT ACK has been returned */ 01019 case I2C_I2STAT_S_RX_PRE_GENCALL_DAT_NACK: 01020 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 01021 break; 01022 01023 /* 01024 * Note that: Return code only let us know a stop condition mixed 01025 * with a repeat start condition in the same code value. 01026 * So we should provide a time-out. In case this is really a stop 01027 * condition, this will return back after time out condition. Otherwise, 01028 * next session that is slave receive data will be completed. 01029 */ 01030 01031 /* A Stop or a repeat start condition */ 01032 case I2C_I2STAT_S_RX_STA_STO_SLVREC_SLVTRX: 01033 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 01034 // enable time out 01035 time_en = 1; 01036 timeout = 0; 01037 break; 01038 01039 /* Writing phase -------------------------------------------------------- */ 01040 /* Own SLA+R has been received, ACK has been returned */ 01041 case I2C_I2STAT_S_TX_SLAR_ACK: 01042 /* Data has been transmitted, ACK has been received */ 01043 case I2C_I2STAT_S_TX_DAT_ACK: 01044 /* 01045 * All data bytes that over-flow the specified receive 01046 * data length, just ignore them. 01047 */ 01048 if ((TransferCfg->tx_count < TransferCfg->tx_length) \ 01049 && (TransferCfg->tx_data != NULL)) { 01050 I2Cx->I2DAT = *txdat++; 01051 TransferCfg->tx_count++; 01052 } 01053 I2Cx->I2CONSET = I2C_I2CONSET_AA; 01054 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 01055 break; 01056 01057 /* Data has been transmitted, NACK has been received, 01058 * that means there's no more data to send, exit now */ 01059 /* 01060 * Note: Don't wait for stop event since in slave transmit mode, 01061 * since there no proof lets us know when a stop signal has been received 01062 * on slave side. 01063 */ 01064 case I2C_I2STAT_S_TX_DAT_NACK: 01065 I2Cx->I2CONSET = I2C_I2CONSET_AA; 01066 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 01067 // enable time out 01068 time_en = 1; 01069 timeout = 0; 01070 break; 01071 01072 // Other status must be captured 01073 default: 01074 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 01075 goto s_error; 01076 //break; 01077 } 01078 } else if (time_en) { 01079 if (timeout++ > I2C_SLAVE_TIME_OUT) { 01080 // it's really a stop condition, goto end stage 01081 goto s_end_stage; 01082 } 01083 } 01084 } 01085 01086 s_end_stage: 01087 /* Clear AA bit to disable ACK on I2C bus */ 01088 I2Cx->I2CONCLR = I2C_I2CONCLR_AAC; 01089 // Check if there's no error during operation 01090 // Update status 01091 TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_DONE; 01092 return SUCCESS; 01093 01094 s_error: 01095 /* Clear AA bit to disable ACK on I2C bus */ 01096 I2Cx->I2CONCLR = I2C_I2CONCLR_AAC; 01097 // Update status 01098 TransferCfg->status = CodeStatus; 01099 return ERROR; 01100 } 01101 01102 else if (Opt == I2C_TRANSFER_INTERRUPT) { 01103 // Setup tx_rx data, callback and interrupt handler 01104 tmp = I2C_getNum(I2Cx); 01105 i2cdat[tmp].txrx_setup = (uint32_t) TransferCfg; 01106 i2cdat[tmp].inthandler = I2C_SlaveHandler; 01107 // Set direction phase, read first 01108 i2cdat[tmp].dir = 1; 01109 01110 // Enable AA 01111 I2Cx->I2CONSET = I2C_I2CONSET_AA; 01112 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC; 01113 I2C_IntCmd(I2Cx, TRUE); 01114 01115 return (SUCCESS); 01116 } 01117 01118 return ERROR; 01119 } 01120 01121 /*********************************************************************//** 01122 * @brief Set Own slave address in I2C peripheral corresponding to 01123 * parameter specified in OwnSlaveAddrConfigStruct. 01124 * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2 01125 * @param[in] OwnSlaveAddrConfigStruct Pointer to a I2C_OWNSLAVEADDR_CFG_Type 01126 * structure that contains the configuration information for the 01127 * specified I2C slave address. 01128 * @return None 01129 **********************************************************************/ 01130 void I2C_SetOwnSlaveAddr(LPC_I2C_TypeDef *I2Cx, I2C_OWNSLAVEADDR_CFG_Type *OwnSlaveAddrConfigStruct) 01131 { 01132 uint32_t tmp; 01133 01134 tmp = (((uint32_t)(OwnSlaveAddrConfigStruct->SlaveAddr_7bit << 1)) \ 01135 | ((OwnSlaveAddrConfigStruct->GeneralCallState == ENABLE) ? 0x01 : 0x00))& I2C_I2ADR_BITMASK; 01136 switch (OwnSlaveAddrConfigStruct->SlaveAddrChannel) { 01137 case 0: 01138 I2Cx->I2ADR0 = tmp; 01139 I2Cx->I2MASK0 = I2C_I2MASK_MASK((uint32_t) \ 01140 (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue)); 01141 break; 01142 case 1: 01143 I2Cx->I2ADR1 = tmp; 01144 I2Cx->I2MASK1 = I2C_I2MASK_MASK((uint32_t) \ 01145 (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue)); 01146 break; 01147 case 2: 01148 I2Cx->I2ADR2 = tmp; 01149 I2Cx->I2MASK2 = I2C_I2MASK_MASK((uint32_t) \ 01150 (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue)); 01151 break; 01152 case 3: 01153 I2Cx->I2ADR3 = tmp; 01154 I2Cx->I2MASK3 = I2C_I2MASK_MASK((uint32_t) \ 01155 (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue)); 01156 break; 01157 } 01158 } 01159 01160 01161 /*********************************************************************//** 01162 * @brief Configures functionality in I2C monitor mode 01163 * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2 01164 * @param[in] MonitorCfgType Monitor Configuration type, should be: 01165 * - I2C_MONITOR_CFG_SCL_OUTPUT: I2C module can 'stretch' 01166 * the clock line (hold it low) until it has had time to 01167 * respond to an I2C interrupt. 01168 * - I2C_MONITOR_CFG_MATCHALL: When this bit is set to '1' 01169 * and the I2C is in monitor mode, an interrupt will be 01170 * generated on ANY address received. 01171 * @param[in] NewState New State of this function, should be: 01172 * - ENABLE: Enable this function. 01173 * - DISABLE: Disable this function. 01174 * @return None 01175 **********************************************************************/ 01176 void I2C_MonitorModeConfig(LPC_I2C_TypeDef *I2Cx, uint32_t MonitorCfgType, FunctionalState NewState) // I2C_MONITOR_CFG_MATCHALL, TRUE 01177 { 01178 if (NewState == ENABLE) { 01179 I2Cx->MMCTRL |= MonitorCfgType; // I2C_MONITOR_CFG_MATCHALL .. I2Cx->MMCTRL |= I2C_I2MMCTRL_MM_ENA 01180 } else { 01181 I2Cx->MMCTRL &= (~MonitorCfgType) & I2C_I2MMCTRL_BITMASK; 01182 } 01183 } 01184 01185 01186 /*********************************************************************//** 01187 * @brief Enable/Disable I2C monitor mode 01188 * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2 01189 * @param[in] NewState New State of this function, should be: 01190 * - ENABLE: Enable monitor mode. 01191 * - DISABLE: Disable monitor mode. 01192 * @return None 01193 **********************************************************************/ 01194 void I2C_MonitorModeCmd(LPC_I2C_TypeDef *I2Cx, FunctionalState NewState) 01195 { 01196 01197 if (NewState == ENABLE) { 01198 I2Cx->MMCTRL |= I2C_I2MMCTRL_MM_ENA; 01199 } else { 01200 I2Cx->MMCTRL &= (~I2C_I2MMCTRL_MM_ENA) & I2C_I2MMCTRL_BITMASK; 01201 } 01202 } 01203 01204 01205 /*********************************************************************//** 01206 * @brief Get data from I2C data buffer in monitor mode. 01207 * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2 01208 * @return None 01209 * Note: In monitor mode, the I2C module may lose the ability to stretch 01210 * the clock (stall the bus) if the ENA_SCL bit is not set. This means that 01211 * the processor will have a limited amount of time to read the contents of 01212 * the data received on the bus. If the processor reads the I2DAT shift 01213 * register, as it ordinarily would, it could have only one bit-time to 01214 * respond to the interrupt before the received data is overwritten by 01215 * new data. 01216 **********************************************************************/ 01217 uint8_t I2C_MonitorGetDatabuffer(LPC_I2C_TypeDef *I2Cx) 01218 { 01219 return ((uint8_t)(I2Cx->I2DATA_BUFFER)); 01220 } 01221 01222 /*********************************************************************//** 01223 * @brief Standard Interrupt handler for I2C0 peripheral 01224 * @param[in] None 01225 * @return None 01226 **********************************************************************/ 01227 void I2C0_StdIntHandler(void) 01228 { 01229 i2cdat[0].inthandler(LPC_I2C0); 01230 } 01231 01232 /*********************************************************************//** 01233 * @brief Standard Interrupt handler for I2C1 peripheral 01234 * @param[in] None 01235 * @return None 01236 **********************************************************************/ 01237 void I2C1_StdIntHandler(void) 01238 { 01239 i2cdat[1].inthandler(LPC_I2C1); 01240 } 01241 01242 /*********************************************************************//** 01243 * @brief Standard Interrupt handler for I2C2 peripheral 01244 * @param[in] None 01245 * @return None 01246 **********************************************************************/ 01247 void I2C2_StdIntHandler(void) 01248 { 01249 i2cdat[2].inthandler(LPC_I2C2); 01250 } 01251 01252 /*********************************************************************//** 01253 * @brief Get data from I2C data buffer in monitor mode. 01254 * @param[in] I2Cx I2C peripheral selected, should be 01255 * - LPC_I2C0 01256 * - LPC_I2C1 01257 * - LPC_I2C2 01258 * @return None 01259 * Note: In monitor mode, the I2C module may lose the ability to stretch 01260 * the clock (stall the bus) if the ENA_SCL bit is not set. This means that 01261 * the processor will have a limited amount of time to read the contents of 01262 * the data received on the bus. If the processor reads the I2DAT shift 01263 * register, as it ordinarily would, it could have only one bit-time to 01264 * respond to the interrupt before the received data is overwritten by 01265 * new data. 01266 ********************************************************************** 01267 BOOL_8 I2C_MonitorHandler(LPC_I2C_TypeDef *I2Cx, uint8_t *buffer, uint32_t size) 01268 { 01269 BOOL_8 ret=FALSE; 01270 01271 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 01272 01273 buffer[I2C_MonitorBufferIndex] = (uint8_t)(I2Cx->I2DATA_BUFFER); 01274 I2C_MonitorBufferIndex++; 01275 if(I2C_MonitorBufferIndex >= size) 01276 { 01277 ret = TRUE; 01278 } 01279 return ret; 01280 } 01281 */ 01282 /** 01283 * @} 01284 */ 01285 01286 #endif /* _I2C */ 01287 01288 /** 01289 * @} 01290 */ 01291 01292 int main() { 01293 01294 Thread thread(blinky); 01295 // LPC_I2C1 01296 uint8_t myByte; 01297 int count =0; 01298 01299 LPC_I2C_TypeDef *I2Cx = LPC_I2C2; 01300 01301 01302 I2C_Init(I2Cx,1000); //* @brief Initializes the I2Cx peripheral with specified parameter. 01303 I2C_Cmd(I2Cx, ENABLE); // * @brief Enable or disable I2C peripheral's operation 01304 I2C_MonitorModeCmd(I2Cx, ENABLE); // * @brief Enable/Disable I2C monitor mode -- I2C_I2MMCTRL_MM_ENA 01305 I2C_MonitorModeConfig(I2Cx, I2C_MONITOR_CFG_MATCHALL, ENABLE); // Configure to catch on all addresses - I2C_MONITOR_CFG_MATCHALL 01306 01307 //I2C_SetClock (LPC_I2C1, 1000); // * @brief Setup clock rate for I2C peripheral 01308 I2Cx->MMCTRL |= I2C_I2MMCTRL_MM_ENA; // enable monitor mode 01309 I2Cx->MMCTRL |= I2C_MONITOR_CFG_MATCHALL; // I2C_MONITOR_CFG_MATCHALL 01310 I2Cx->MMCTRL |= (1<<1); // Enable ENA_SCL bit 01311 I2Cx->I2CONSET |= I2C_I2CONSET_I2EN; // Enable the i2c interface 01312 I2C_IntCmd(I2Cx, TRUE); 01313 01314 /* interrupt handler */ 01315 // NVIC_EnableIRQ(I2C1_IRQn); 01316 pc.printf(" **************** **************** **************** **************** **************** \n\r"); 01317 printf("I2Cx->MMCTRL == %x \n\r",I2Cx->MMCTRL); 01318 wait(3); 01319 I2Cx->I2CONCLR = I2C_I2CONSET_STA | I2C_I2CONCLR_STAC; 01320 while (1) { 01321 // pc.printf("dataBuff has %x in it , and the count is %x \n\r",myByte, count++); 01322 01323 //uint8_t retdat; 01324 //pc.printf("Waiting for a Byte to come in\r\n"); 01325 //uint32_t aWord = I2C_GetByte (LPC_I2C1, &retdat, FALSE); 01326 //pc.printf(" retDat = %x, stat = %x \n\r",retdat,aWord); 01327 //pc.printf("Data Buffer *********** = %x !\n\r",I2Cx->I2DATA_BUFFER); 01328 I2Cx->I2CONCLR = I2C_I2CONSET_STA | I2C_I2CONCLR_STAC; 01329 01330 01331 // I2Cx->I2DATA_BUFFER = 0xff; 01332 01333 pc.printf("Status = %x\n\r",I2Cx->I2STAT & I2C_STAT_CODE_BITMASK); 01334 pc.printf("I2CONSET = %x\n\r",I2Cx->I2CONSET); 01335 pc.printf("Interrupt = %x\n\r",I2C_I2CONSET_SI & I2Cx->I2CONSET); // what is the value of the interupt 01336 pc.printf("I2C_I2CONSET_STA = %x\n\r",I2Cx->I2CONSET & I2C_I2CONSET_STA); // I2C Status Register. 01337 pc.printf("I2C_I2CONCLR_STAC = %x\n\r",I2Cx->I2CONSET & I2C_I2CONCLR_STAC); 01338 pc.printf("Data Byte = %x \n\r,", I2Cx->I2DAT & I2C_I2DAT_BITMASK); 01339 01340 01341 // 0xFF into the DAT 01342 01343 01344 //pc.printf("the count is %x \n\r\n\r",count++); 01345 // Clear the interrupt flag 01346 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 01347 wait(0.3); 01348 01349 // Check SI flag ready 01350 if ((I2Cx->I2CONSET & I2C_I2CONSET_SI) ){ 01351 // if(1) { 01352 pc.printf("I2Cx->I2CONSET & I2C_I2CONSET_SI is true \r\n"); 01353 myByte = I2C_MonitorGetDatabuffer(I2Cx); 01354 // Clear the interrupt flag 01355 I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; 01356 pc.printf("dataBuff has %x in it , and the count is %x \n\r",myByte, count++); 01357 } 01358 else { 01359 pc.printf("I2C_I2CONSET_SI not set count = %x \n\r",count++); 01360 } 01361 pc.printf(" **************** \n\r"); 01362 wait(0.3); 01363 01364 } 01365 } 01366 01367 01368 01369 01370 01371 01372 01373 01374 01375 01376 /* 01377 01378 //LPC_I2C1->I2CONCLR = 0x04; 01379 01380 01381 While SI is set, the low period of the serial 01382 clock on the SCL line is stretched, and the 01383 serial transfer is suspended. When SCL is HIGH, it is unaffected by the state of the SI flag. 01384 SI must be reset by software, by writing a 1 01385 to the SIC bit in I2CONCLR register. The SI bit 01386 should be cleared only after the required bit(s) has (have) been set and the value in I2DAT 01387 has been loaded or read. 01388 */ 01389
Generated on Sat Jul 16 2022 03:25:10 by
1.7.2