Bose Automation / Mbed 2 deprecated mbed_USBserial

Dependencies:   mbed-rtos mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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