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