NXP's driver library for LPC17xx, ported to mbed's online compiler. Not tested! I had to fix a lot of warings and found a couple of pretty obvious bugs, so the chances are there are more. Original: http://ics.nxp.com/support/documents/microcontrollers/zip/lpc17xx.cmsis.driver.library.zip

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lpc17xx_i2c.c Source File

lpc17xx_i2c.c

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