lpc-field

Template project for programming NXP's LPC1768 MCUs
git clone git://git.mdnr.space/lpc-field
Log | Files | Refs | README | LICENSE

lpc17xx_i2c.c (39359B)


      1 /**********************************************************************
      2 * $Id$		lpc17xx_i2c.c				2011-03-31
      3 *//**
      4 * @file		lpc17xx_i2c.c
      5 * @brief	Contains all functions support for I2C firmware
      6 * 			library on LPC17xx
      7 * @version	2.1
      8 * @date		31. Mar. 2011
      9 * @author	NXP MCU SW Application Team
     10 *
     11 * Copyright(C) 2010, NXP Semiconductor
     12 * All rights reserved.
     13 *
     14 ***********************************************************************
     15 * Software that is described herein is for illustrative purposes only
     16 * which provides customers with programming information regarding the
     17 * products. This software is supplied "AS IS" without any warranties.
     18 * NXP Semiconductors assumes no responsibility or liability for the
     19 * use of the software, conveys no license or title under any patent,
     20 * copyright, or mask work right to the product. NXP Semiconductors
     21 * reserves the right to make changes in the software without
     22 * notification. NXP Semiconductors also make no representation or
     23 * warranty that such application will be suitable for the specified
     24 * use without further testing or modification.
     25 * Permission to use, copy, modify, and distribute this software and its
     26 * documentation is hereby granted, under NXP Semiconductors'
     27 * relevant copyright in the software, without fee, provided that it
     28 * is used in conjunction with NXP Semiconductors microcontrollers.  This
     29 * copyright, permission, and disclaimer notice must appear in all copies of
     30 * this code.
     31 **********************************************************************/
     32 
     33 /* Peripheral group ----------------------------------------------------------- */
     34 /** @addtogroup I2C
     35  * @{
     36  */
     37 
     38 /* Includes ------------------------------------------------------------------- */
     39 #include "lpc17xx_i2c.h"
     40 #include "lpc17xx_clkpwr.h"
     41 #include "lpc17xx_pinsel.h"
     42 
     43 
     44 /* If this source file built with example, the LPC17xx FW library configuration
     45  * file in each example directory ("lpc17xx_libcfg.h") must be included,
     46  * otherwise the default FW library configuration file must be included instead
     47  */
     48 #ifdef __BUILD_WITH_EXAMPLE__
     49 #include "lpc17xx_libcfg.h"
     50 #else
     51 #include "lpc17xx_libcfg_default.h"
     52 #endif /* __BUILD_WITH_EXAMPLE__ */
     53 
     54 
     55 #ifdef _I2C
     56 
     57 
     58 /* Private Types -------------------------------------------------------------- */
     59 /** @defgroup I2C_Private_Types I2C Private Types
     60  * @{
     61  */
     62 
     63 /**
     64  * @brief I2C device configuration structure type
     65  */
     66 typedef struct
     67 {
     68   uint32_t      txrx_setup; 						/* Transmission setup */
     69   int32_t		dir;								/* Current direction phase, 0 - write, 1 - read */
     70 } I2C_CFG_T;
     71 
     72 /**
     73  * @}
     74  */
     75 
     76 /* Private Variables ---------------------------------------------------------- */
     77 /**
     78  * @brief II2C driver data for I2C0, I2C1 and I2C2
     79  */
     80 static I2C_CFG_T i2cdat[3];
     81 
     82 static uint32_t I2C_MasterComplete[3];
     83 static uint32_t I2C_SlaveComplete[3];
     84 
     85 static uint32_t I2C_MonitorBufferIndex;
     86 
     87 /* Private Functions ---------------------------------------------------------- */
     88 
     89 /* Get I2C number */
     90 static int32_t I2C_getNum(LPC_I2C_TypeDef *I2Cx);
     91 
     92 /* Generate a start condition on I2C bus (in master mode only) */
     93 static uint32_t I2C_Start (LPC_I2C_TypeDef *I2Cx);
     94 
     95 /* Generate a stop condition on I2C bus (in master mode only) */
     96 static void I2C_Stop (LPC_I2C_TypeDef *I2Cx);
     97 
     98 /* I2C send byte subroutine */
     99 static uint32_t I2C_SendByte (LPC_I2C_TypeDef *I2Cx, uint8_t databyte);
    100 
    101 /* I2C get byte subroutine */
    102 static uint32_t I2C_GetByte (LPC_I2C_TypeDef *I2Cx, uint8_t *retdat, Bool ack);
    103 
    104 /* I2C set clock (hz) */
    105 static void I2C_SetClock (LPC_I2C_TypeDef *I2Cx, uint32_t target_clock);
    106 
    107 /*--------------------------------------------------------------------------------*/
    108 /********************************************************************//**
    109  * @brief		Convert from I2C peripheral to number
    110  * @param[in]	I2Cx: I2C peripheral selected, should be:
    111  * 				- LPC_I2C0
    112  * 				- LPC_I2C1
    113  * 				- LPC_I2C2
    114  * @return 		I2C number, could be: 0..2
    115  *********************************************************************/
    116 static int32_t I2C_getNum(LPC_I2C_TypeDef *I2Cx){
    117 	if (I2Cx == LPC_I2C0) {
    118 		return (0);
    119 	} else if (I2Cx == LPC_I2C1) {
    120 		return (1);
    121 	} else if (I2Cx == LPC_I2C2) {
    122 		return (2);
    123 	}
    124 	return (-1);
    125 }
    126 
    127 /********************************************************************//**
    128  * @brief		Generate a start condition on I2C bus (in master mode only)
    129  * @param[in]	I2Cx: I2C peripheral selected, should be:
    130  * 				- LPC_I2C0
    131  * 				- LPC_I2C1
    132  * 				- LPC_I2C2
    133  * @return 		value of I2C status register after generate a start condition
    134  *********************************************************************/
    135 static uint32_t I2C_Start (LPC_I2C_TypeDef *I2Cx)
    136 {
    137 	// Reset STA, STO, SI
    138 	I2Cx->I2CONCLR = I2C_I2CONCLR_SIC|I2C_I2CONCLR_STOC|I2C_I2CONCLR_STAC;
    139 
    140 	// Enter to Master Transmitter mode
    141 	I2Cx->I2CONSET = I2C_I2CONSET_STA;
    142 
    143 	// Wait for complete
    144 	while (!(I2Cx->I2CONSET & I2C_I2CONSET_SI));
    145 	I2Cx->I2CONCLR = I2C_I2CONCLR_STAC;
    146 	return (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK);
    147 }
    148 
    149 /********************************************************************//**
    150  * @brief		Generate a stop condition on I2C bus (in master mode only)
    151  * @param[in]	I2Cx: I2C peripheral selected, should be:
    152  * 				- LPC_I2C0
    153  * 				- LPC_I2C1
    154  * 				- LPC_I2C2
    155  * @return 		None
    156  *********************************************************************/
    157 static void I2C_Stop (LPC_I2C_TypeDef *I2Cx)
    158 {
    159 
    160 	/* Make sure start bit is not active */
    161 	if (I2Cx->I2CONSET & I2C_I2CONSET_STA)
    162 	{
    163 		I2Cx->I2CONCLR = I2C_I2CONCLR_STAC;
    164 	}
    165 
    166 	I2Cx->I2CONSET = I2C_I2CONSET_STO|I2C_I2CONSET_AA;
    167 
    168 	I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;
    169 }
    170 
    171 /********************************************************************//**
    172  * @brief		Send a byte
    173  * @param[in]	I2Cx: I2C peripheral selected, should be:
    174  * 				- LPC_I2C0
    175  * 				- LPC_I2C1
    176  * 				- LPC_I2C2
    177  * @param[in]	databyte: number of byte
    178  * @return 		value of I2C status register after sending
    179  *********************************************************************/
    180 static uint32_t I2C_SendByte (LPC_I2C_TypeDef *I2Cx, uint8_t databyte)
    181 {
    182 	uint32_t CodeStatus = I2Cx->I2STAT & I2C_STAT_CODE_BITMASK;
    183 
    184 	if((CodeStatus != I2C_I2STAT_M_TX_START) &&
    185 		(CodeStatus != I2C_I2STAT_M_TX_RESTART) &&
    186 		(CodeStatus != I2C_I2STAT_M_TX_SLAW_ACK)  &&
    187 		(CodeStatus != I2C_I2STAT_M_TX_DAT_ACK)  )
    188 	{
    189 		return CodeStatus;
    190 	}
    191 	
    192 	/* Make sure start bit is not active */
    193 	if (I2Cx->I2CONSET & I2C_I2CONSET_STA)
    194 	{
    195 		I2Cx->I2CONCLR = I2C_I2CONCLR_STAC;
    196 	}
    197 	I2Cx->I2DAT = databyte & I2C_I2DAT_BITMASK;
    198 
    199 	I2Cx->I2CONSET = I2C_I2CONSET_AA;
    200 
    201 	I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;
    202 
    203 	return (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK);
    204 }
    205 
    206 /********************************************************************//**
    207  * @brief		Get a byte
    208  * @param[in]	I2Cx: I2C peripheral selected, should be:
    209  * 				- LPC_I2C0
    210  * 				- LPC_I2C1
    211  * 				- LPC_I2C2
    212  * @param[out]	retdat	pointer to return data
    213  * @param[in]	ack		assert acknowledge or not, should be: TRUE/FALSE
    214  * @return 		value of I2C status register after sending
    215  *********************************************************************/
    216 static uint32_t I2C_GetByte (LPC_I2C_TypeDef *I2Cx, uint8_t *retdat, Bool ack)
    217 {
    218 	*retdat = (uint8_t) (I2Cx->I2DAT & I2C_I2DAT_BITMASK);
    219 	
    220 	if (ack == TRUE)
    221 	{
    222 		I2Cx->I2CONSET = I2C_I2CONSET_AA;
    223 	}
    224 	else
    225 	{
    226 		I2Cx->I2CONCLR = I2C_I2CONCLR_AAC;
    227 	}
    228 
    229 	I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;
    230 	
    231 	return (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK);
    232 }
    233 
    234 /*********************************************************************//**
    235  * @brief 		Setup clock rate for I2C peripheral
    236  * @param[in] 	I2Cx	I2C peripheral selected, should be:
    237  * 				- LPC_I2C0
    238  * 				- LPC_I2C1
    239  * 				- LPC_I2C2
    240  * @param[in]	target_clock : clock of SSP (Hz)
    241  * @return 		None
    242  ***********************************************************************/
    243 static void I2C_SetClock (LPC_I2C_TypeDef *I2Cx, uint32_t target_clock)
    244 {
    245 	uint32_t temp;
    246 
    247 	CHECK_PARAM(PARAM_I2Cx(I2Cx));
    248 
    249 	// Get PCLK of I2C controller
    250 	if (I2Cx == LPC_I2C0)
    251 	{
    252 		temp = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_I2C0) / target_clock;
    253 	}
    254 	else if (I2Cx == LPC_I2C1)
    255 	{
    256 		temp = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_I2C1) / target_clock;
    257 	}
    258 	else if (I2Cx == LPC_I2C2)
    259 	{
    260 		temp = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_I2C2) / target_clock;
    261 	}
    262 
    263 	/* Set the I2C clock value to register */
    264 	I2Cx->I2SCLH = (uint32_t)(temp / 2);
    265 	I2Cx->I2SCLL = (uint32_t)(temp - I2Cx->I2SCLH);
    266 }
    267 /* End of Private Functions --------------------------------------------------- */
    268 
    269 
    270 /* Public Functions ----------------------------------------------------------- */
    271 /** @addtogroup I2C_Public_Functions
    272  * @{
    273  */
    274 
    275 /********************************************************************//**
    276  * @brief		Initializes the I2Cx peripheral with specified parameter.
    277  * @param[in]	I2Cx	I2C peripheral selected, should be
    278  * 				- LPC_I2C0
    279  * 				- LPC_I2C1
    280  * 				- LPC_I2C2
    281  * @param[in]	clockrate Target clock rate value to initialized I2C
    282  * 				peripheral (Hz)
    283  * @return 		None
    284  *********************************************************************/
    285 void I2C_Init(LPC_I2C_TypeDef *I2Cx, uint32_t clockrate)
    286 {
    287 	CHECK_PARAM(PARAM_I2Cx(I2Cx));
    288 
    289 	if (I2Cx==LPC_I2C0)
    290 	{
    291 		/* Set up clock and power for I2C0 module */
    292 		CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C0, ENABLE);
    293 		/* As default, peripheral clock for I2C0 module
    294 		 * is set to FCCLK / 2 */
    295 		CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_I2C0, CLKPWR_PCLKSEL_CCLK_DIV_2);
    296 	}
    297 	else if (I2Cx==LPC_I2C1)
    298 	{
    299 		/* Set up clock and power for I2C1 module */
    300 		CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C1, ENABLE);
    301 		/* As default, peripheral clock for I2C1 module
    302 		 * is set to FCCLK / 2 */
    303 		CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_I2C1, CLKPWR_PCLKSEL_CCLK_DIV_2);
    304 	}
    305 	else if (I2Cx==LPC_I2C2)
    306 	{
    307 		/* Set up clock and power for I2C2 module */
    308 		CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C2, ENABLE);
    309 		/* As default, peripheral clock for I2C2 module
    310 		 * is set to FCCLK / 2 */
    311 		CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_I2C2, CLKPWR_PCLKSEL_CCLK_DIV_2);
    312 	}
    313 	else {
    314 		// Up-Support this device
    315 		return;
    316 	}
    317 
    318     /* Set clock rate */
    319     I2C_SetClock(I2Cx, clockrate);
    320     /* Set I2C operation to default */
    321     I2Cx->I2CONCLR = (I2C_I2CONCLR_AAC | I2C_I2CONCLR_STAC | I2C_I2CONCLR_I2ENC);
    322 }
    323 
    324 /*********************************************************************//**
    325  * @brief		De-initializes the I2C peripheral registers to their
    326  *                  default reset values.
    327  * @param[in]	I2Cx	I2C peripheral selected, should be
    328  *  			- LPC_I2C0
    329  * 				- LPC_I2C1
    330  * 				- LPC_I2C2
    331  * @return 		None
    332  **********************************************************************/
    333 void I2C_DeInit(LPC_I2C_TypeDef* I2Cx)
    334 {
    335 	CHECK_PARAM(PARAM_I2Cx(I2Cx));
    336 
    337 	/* Disable I2C control */
    338 	I2Cx->I2CONCLR = I2C_I2CONCLR_I2ENC;
    339 
    340 	if (I2Cx==LPC_I2C0)
    341 	{
    342 		/* Disable power for I2C0 module */
    343 		CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C0, DISABLE);
    344 	}
    345 	else if (I2Cx==LPC_I2C1)
    346 	{
    347 		/* Disable power for I2C1 module */
    348 		CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C1, DISABLE);
    349 	}
    350 	else if (I2Cx==LPC_I2C2)
    351 	{
    352 		/* Disable power for I2C2 module */
    353 		CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C2, DISABLE);
    354 	}
    355 }
    356 
    357 /*********************************************************************//**
    358  * @brief		Enable or disable I2C peripheral's operation
    359  * @param[in]	I2Cx I2C peripheral selected, should be
    360  *  			- LPC_I2C0
    361  * 				- LPC_I2C1
    362  * 				- LPC_I2C2
    363  * @param[in]	NewState New State of I2Cx peripheral's operation
    364  * @return 		none
    365  **********************************************************************/
    366 void I2C_Cmd(LPC_I2C_TypeDef* I2Cx, en_I2C_Mode Mode,  FunctionalState NewState)
    367 {
    368 	CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
    369 	CHECK_PARAM(PARAM_I2Cx(I2Cx));
    370 
    371 	if (NewState == ENABLE)
    372 	{
    373 		if(Mode != I2C_SLAVE_MODE)
    374 			I2Cx->I2CONSET = I2C_I2CONSET_I2EN;
    375 		else
    376 			I2Cx->I2CONSET = I2C_I2CONSET_I2EN | I2C_I2CONSET_AA;
    377 	}
    378 	else
    379 	{
    380 		I2Cx->I2CONCLR = I2C_I2CONCLR_I2ENC;
    381 	}
    382 }
    383 
    384 /*********************************************************************//**
    385  * @brief 		Enable/Disable interrupt for I2C peripheral
    386  * @param[in]	I2Cx	I2C peripheral selected, should be:
    387  * 				- LPC_I2C0
    388  * 				- LPC_I2C1
    389  * 				- LPC_I2C2
    390  * @param[in]	NewState	New State of I2C peripheral interrupt in NVIC core
    391  * 				should be:
    392  * 				- ENABLE: enable interrupt for this I2C peripheral
    393  * 				- DISABLE: disable interrupt for this I2C peripheral
    394  * @return 		None
    395  **********************************************************************/
    396 void I2C_IntCmd (LPC_I2C_TypeDef *I2Cx, Bool NewState)
    397 {
    398 	if (NewState)
    399 	{
    400 		if(I2Cx == LPC_I2C0)
    401 		{
    402 			NVIC_EnableIRQ(I2C0_IRQn);
    403 		}
    404 		else if (I2Cx == LPC_I2C1)
    405 		{
    406 			NVIC_EnableIRQ(I2C1_IRQn);
    407 		}
    408 		else if (I2Cx == LPC_I2C2)
    409 		{
    410 			NVIC_EnableIRQ(I2C2_IRQn);
    411 		}
    412 	}
    413 	else
    414 	{
    415 		if(I2Cx == LPC_I2C0)
    416 		{
    417 			NVIC_DisableIRQ(I2C0_IRQn);
    418 		}
    419 		else if (I2Cx == LPC_I2C1)
    420 		{
    421 			NVIC_DisableIRQ(I2C1_IRQn);
    422 		}
    423 		else if (I2Cx == LPC_I2C2)
    424 		{
    425 			NVIC_DisableIRQ(I2C2_IRQn);
    426 		}
    427 	}
    428     return;
    429 }
    430 
    431 
    432 /*********************************************************************//**
    433  * @brief 		Handle I2C Master states.
    434  * @param[in]	I2Cx	I2C peripheral selected, should be:
    435  * 				- LPC_I2C
    436  * 				- LPC_I2C1
    437  * 				- LPC_I2C2
    438  * @param[in]	CodeStatus	I2C state
    439  * @param[in]	TransferCfg   Pointer to a I2C_S_SETUP_Type structure that
    440  * 								contains specified information about the
    441  * 								configuration for master transfer.
    442  * @return 		It can be
    443  *				- I2C_OK
    444  *				-I2C_BYTE_RECV
    445  *				-I2C_BYTE_SENT
    446  *				-I2C_SEND_END
    447  *				-I2C_RECV_END
    448  *				- I2C_ERR
    449  *				- I2C_NAK_RECV
    450  **********************************************************************/
    451 int32_t I2C_MasterHanleStates(LPC_I2C_TypeDef  *I2Cx, uint32_t CodeStatus, I2C_M_SETUP_Type *TransferCfg)
    452 {
    453 	uint8_t *txdat;
    454 	uint8_t *rxdat;
    455 	uint8_t tmp;
    456 	int32_t Ret = I2C_OK;
    457 	
    458 	//get buffer to send/receive
    459 	txdat = (uint8_t *) &TransferCfg->tx_data[TransferCfg->tx_count];
    460 	rxdat = (uint8_t *) &TransferCfg->rx_data[TransferCfg->rx_count];
    461 
    462 	switch(CodeStatus)
    463 	{
    464 		case I2C_I2STAT_M_TX_START:
    465 		case I2C_I2STAT_M_TX_RESTART:
    466 		//case I2C_I2STAT_M_RX_START:
    467 		//case I2C_I2STAT_M_RX_RESTART
    468 			// Send data first
    469 			if(TransferCfg->tx_count < TransferCfg->tx_length)
    470 			{
    471 				/* Send slave address + WR direction bit = 0 ----------------------------------- */
    472 				I2C_SendByte(I2Cx, (TransferCfg->sl_addr7bit << 1));
    473 				Ret = I2C_BYTE_SENT;
    474 			}
    475 			else if (TransferCfg->rx_count  < TransferCfg->rx_length)
    476 			{
    477 				/* Send slave address + RD direction bit = 1 ----------------------------------- */
    478 				I2C_SendByte(I2Cx, ((TransferCfg->sl_addr7bit << 1) | 0x01));
    479 				Ret = I2C_BYTE_SENT;
    480 			}
    481 			break;
    482 		case I2C_I2STAT_M_TX_SLAW_ACK:
    483 		case I2C_I2STAT_M_TX_DAT_ACK:
    484 			
    485 			if(TransferCfg->tx_count < TransferCfg->tx_length)
    486 			{
    487 				I2C_SendByte(I2Cx, *txdat);
    488 				
    489 				txdat++;
    490 
    491 				TransferCfg->tx_count++;
    492 
    493 				Ret = I2C_BYTE_SENT;
    494 			}
    495 			else
    496 			{
    497 				I2C_Stop(I2Cx);
    498 
    499 				Ret = I2C_SEND_END;
    500 				
    501 			}
    502 			break;
    503 		case I2C_I2STAT_M_TX_DAT_NACK:
    504 			I2C_Stop(I2Cx);
    505 			Ret = I2C_SEND_END;
    506 			break;
    507 		case I2C_I2STAT_M_RX_ARB_LOST:
    508 		//case I2C_I2STAT_M_TX_ARB_LOST:
    509 			I2Cx->I2CONSET = I2C_I2CONSET_STA|I2C_I2CONSET_AA;
    510 			I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;
    511 			break;
    512 		case I2C_I2STAT_M_RX_SLAR_ACK:
    513 			I2Cx->I2CONSET = I2C_I2CONSET_AA;
    514 			I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;
    515 
    516 			Ret = I2C_BYTE_RECV;
    517 			break;
    518 		case I2C_I2STAT_M_RX_DAT_ACK:
    519 			if (TransferCfg->rx_count <TransferCfg->rx_length)
    520 			{
    521 				if (TransferCfg->rx_count < (TransferCfg->rx_length - 2))
    522 				{
    523 					I2C_GetByte(I2Cx, &tmp, TRUE);
    524 
    525 					Ret = I2C_BYTE_RECV;
    526 				}
    527 				else  // the next byte is the last byte, send NACK instead.
    528 				 {
    529 					I2C_GetByte(I2Cx, &tmp, FALSE);
    530 					Ret = I2C_BYTE_RECV;
    531 				 }
    532 				*rxdat++ = tmp;
    533 
    534 				TransferCfg->rx_count++;
    535 			}
    536 			 else
    537 			 {
    538 				Ret = I2C_RECV_END;
    539 			}
    540 			
    541 			break;
    542 		case I2C_I2STAT_M_RX_DAT_NACK:
    543 			I2C_GetByte(I2Cx, &tmp, FALSE);
    544 			*rxdat++ = tmp;
    545 			TransferCfg->rx_count++;
    546 			I2C_Stop(I2Cx);
    547 			Ret = I2C_RECV_END;
    548 			break;
    549 		case I2C_I2STAT_M_RX_SLAR_NACK:
    550 		case I2C_I2STAT_M_TX_SLAW_NACK:
    551 		case I2C_I2STAT_BUS_ERROR:
    552 			// Send STOP condition
    553 			I2C_Stop(I2Cx);
    554 			Ret = I2C_ERR;
    555 			break;
    556 		/* No status information */
    557 		case I2C_I2STAT_NO_INF:
    558 		default:
    559 			I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;
    560 			break;
    561 	}
    562 	
    563 	return Ret;
    564 }
    565 
    566 /*********************************************************************//**
    567  * @brief 		Handle I2C Slave states.
    568  * @param[in]	I2Cx	I2C peripheral selected, should be:
    569  * 				- LPC_I2C
    570  * 				- LPC_I2C1
    571  * 				- LPC_I2C2
    572  * @param[in]	CodeStatus	I2C state
    573  * @param[in]	TransferCfg   Pointer to a I2C_S_SETUP_Type structure that
    574  * 								contains specified information about the
    575  * 								configuration for master transfer.
    576  * @return 		It can be
    577  *				- I2C_OK
    578  *				-I2C_BYTE_RECV
    579  *				-I2C_BYTE_SENT
    580  *				-I2C_SEND_END
    581  *				-I2C_RECV_END
    582  *				- I2C_ERR
    583  *				- I2C_NAK_RECV
    584  **********************************************************************/
    585 int32_t I2C_SlaveHanleStates(LPC_I2C_TypeDef  *I2Cx, uint32_t CodeStatus, I2C_S_SETUP_Type *TransferCfg)
    586 {
    587 
    588 	int32_t Ret = I2C_OK;
    589 	uint8_t *txdat;
    590 	uint8_t *rxdat;
    591 
    592 	//get buffer to send/receive
    593 	txdat = (uint8_t *) &TransferCfg->tx_data[TransferCfg->tx_count];
    594 	rxdat = (uint8_t *) &TransferCfg->rx_data[TransferCfg->rx_count];
    595 	
    596 	switch (CodeStatus)
    597 	{
    598 		/* Reading phase -------------------------------------------------------- */
    599 		/* Own SLA+R has been received, ACK has been returned */
    600 		case I2C_I2STAT_S_RX_SLAW_ACK:
    601 
    602 		/* General call address has been received, ACK has been returned */
    603 		case I2C_I2STAT_S_RX_GENCALL_ACK:
    604 			I2Cx->I2CONSET = I2C_I2CONSET_AA;
    605 			I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;
    606 			break;
    607 		/* Arbitration has been lost in Slave Address + R/W bit as bus Master. General Call has
    608 			been received and ACK has been returned.*/
    609 		case I2C_I2STAT_S_RX_ARB_LOST_M_GENCALL:
    610 			I2Cx->I2CONSET = I2C_I2CONSET_AA|I2C_I2CONSET_STA;
    611 			I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;
    612 			break;
    613 		/* Previously addressed with own SLA;
    614 		 * DATA byte has been received;
    615 		 * ACK has been returned */
    616 		case I2C_I2STAT_S_RX_ARB_LOST_M_SLA:
    617 		case I2C_I2STAT_S_RX_PRE_SLA_DAT_ACK:
    618 
    619 			/*
    620 			 * All data bytes that over-flow the specified receive
    621 			 * data length, just ignore them.
    622 			 */
    623 			if ((TransferCfg->rx_count < TransferCfg->rx_length) && (TransferCfg->rx_data != NULL))
    624 			{
    625 				*rxdat++ = (uint8_t)I2Cx->I2DAT;
    626 
    627 				TransferCfg->rx_count++;
    628 
    629 				Ret = I2C_BYTE_RECV;
    630 			}
    631 			if(TransferCfg->rx_count == (TransferCfg->rx_length) ) {
    632 				I2Cx->I2CONCLR = I2C_I2CONCLR_AAC|I2C_I2CONCLR_SIC;
    633 				Ret = I2C_BYTE_RECV;
    634 			}
    635 			else {
    636 				I2Cx->I2CONSET = I2C_I2CONSET_AA;
    637 				I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;
    638 			}
    639 			
    640 			break;
    641 		/* DATA has been received, Only the first data byte will be received with ACK. Additional
    642 				data will be received with NOT ACK. */
    643 		case I2C_I2STAT_S_RX_PRE_GENCALL_DAT_ACK:
    644 			if ((TransferCfg->rx_count < TransferCfg->rx_length) && (TransferCfg->rx_data != NULL))
    645 			{
    646 				*rxdat++ = (uint8_t)I2Cx->I2DAT;
    647 
    648 				TransferCfg->rx_count++;
    649 
    650 				Ret = I2C_BYTE_RECV;
    651 			}
    652 			I2Cx->I2CONCLR = I2C_I2CONCLR_AAC|I2C_I2CONCLR_SIC;
    653 			break;
    654 
    655 		/* Writing phase -------------------------------------------------------- */
    656 		/* Own SLA+R has been received, ACK has been returned */
    657 		case I2C_I2STAT_S_TX_SLAR_ACK:
    658 
    659 		/* Data has been transmitted, ACK has been received */
    660 		case I2C_I2STAT_S_TX_DAT_ACK:
    661 			/*
    662 			 * All data bytes that over-flow the specified receive
    663 			 * data length, just ignore them.
    664 			 */
    665 			if ((TransferCfg->tx_count < TransferCfg->tx_length) && (TransferCfg->tx_data != NULL))
    666 			{
    667 				I2Cx->I2DAT = *txdat++;
    668 
    669 				TransferCfg->tx_count++;
    670 
    671 				Ret = I2C_BYTE_SENT;
    672 			}
    673 
    674 			I2Cx->I2CONSET = I2C_I2CONSET_AA;
    675 			I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;
    676 			break;
    677 		/* Arbitration lost in Slave Address and R/W bit as bus Master. Own Slave Address + Read
    678 				has been received, ACK has been returned. */
    679 		case I2C_I2STAT_S_TX_ARB_LOST_M_SLA:
    680 			if ((TransferCfg->tx_count < TransferCfg->tx_length) && (TransferCfg->tx_data != NULL))
    681 			{
    682 				I2Cx->I2DAT = *txdat++;
    683 
    684 				TransferCfg->tx_count++;
    685 
    686 				Ret = I2C_BYTE_SENT;
    687 			}
    688 			I2Cx->I2CONSET = I2C_I2CONSET_AA|I2C_I2CONSET_STA;
    689 			I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;
    690 			break;
    691 			
    692 		case I2C_I2STAT_S_TX_LAST_DAT_ACK:
    693 		/* Data has been transmitted, NACK has been received,
    694 		 * that means there's no more data to send, exit now */
    695 		/*
    696 		 * Note: Don't wait for stop event since in slave transmit mode,
    697 		 * since there no proof lets us know when a stop signal has been received
    698 		 * on slave side.
    699 		 */
    700 		case I2C_I2STAT_S_TX_DAT_NACK:
    701 			I2Cx->I2CONSET = I2C_I2CONSET_AA;
    702 			I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;
    703 			Ret = I2C_SEND_END;
    704 			break;
    705 
    706 		/* Previously addressed with own SLA;
    707 		 * DATA byte has been received;
    708 		 * NOT ACK has been returned */
    709 		case I2C_I2STAT_S_RX_PRE_SLA_DAT_NACK:
    710 
    711 		/* DATA has been received, NOT ACK has been returned */
    712 		case I2C_I2STAT_S_RX_PRE_GENCALL_DAT_NACK:
    713 			I2Cx->I2CONSET = I2C_I2CONSET_AA;
    714 			I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;
    715 			Ret = I2C_RECV_END;
    716 			break;
    717 
    718 		/*
    719 		 * Note that: Return code only let us know a stop condition mixed
    720 		 * with a repeat start condition in the same code value.
    721 		 * So we should provide a time-out. In case this is really a stop
    722 		 * condition, this will return back after time out condition. Otherwise,
    723 		 * next session that is slave receive data will be completed.
    724 		 */
    725 
    726 		/* A Stop or a repeat start condition */
    727 		case I2C_I2STAT_S_RX_STA_STO_SLVREC_SLVTRX:
    728 			I2Cx->I2CONSET = I2C_I2CONSET_AA;
    729 			I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;
    730 			Ret = I2C_STA_STO_RECV;
    731 			break;
    732 		
    733 		/* No status information */
    734 		case I2C_I2STAT_NO_INF:
    735 		/* Other status must be captured */
    736 		default:
    737 			I2Cx->I2CONSET = I2C_I2CONSET_AA;
    738 			I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;
    739 			break;
    740 		
    741 	}
    742 
    743 	return Ret;
    744 }
    745 /*********************************************************************//**
    746  * @brief 		General Master Interrupt handler for I2C peripheral
    747  * @param[in]	I2Cx	I2C peripheral selected, should be:
    748  * 				- LPC_I2C
    749  * 				- LPC_I2C1
    750  * 				- LPC_I2C2
    751  * @return 		None
    752  **********************************************************************/
    753 void I2C_MasterHandler(LPC_I2C_TypeDef  *I2Cx)
    754 {
    755 	uint32_t i2cId = I2C_getNum(I2Cx);
    756 	uint8_t returnCode;
    757 	I2C_M_SETUP_Type *txrx_setup;
    758 	int32_t Ret = I2C_OK;
    759 
    760 	txrx_setup = (I2C_M_SETUP_Type *) i2cdat[i2cId].txrx_setup;
    761 
    762 	returnCode = (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK);
    763 
    764 	// Save current status
    765 	txrx_setup->status = returnCode;
    766 
    767 	Ret = I2C_MasterHanleStates(I2Cx, returnCode, txrx_setup);
    768 
    769 	if(I2C_CheckError(Ret))
    770 	{
    771 		if(txrx_setup->retransmissions_count < txrx_setup->retransmissions_max)
    772 		{
    773 			// Retry
    774 			txrx_setup->retransmissions_count ++;
    775 			txrx_setup->tx_count = 0;
    776 			txrx_setup->rx_count = 0;
    777 			// Reset STA, STO, SI
    778 	        I2Cx->I2CONCLR = I2C_I2CONCLR_SIC|I2C_I2CONCLR_STOC|I2C_I2CONCLR_STAC;
    779 			I2Cx->I2CONSET = I2C_I2CONSET_STA;
    780 			return;
    781 		}
    782 		else
    783 		{
    784 			goto s_int_end;
    785 		}
    786 	}
    787 	else if (Ret & I2C_SEND_END)
    788 	{
    789 		// If no need to wait for data from Slave
    790 		if(txrx_setup->rx_count >= (txrx_setup->rx_length)) 
    791 		{
    792 			goto s_int_end;
    793 		}
    794 		else	// Start to wait for data from Slave
    795 		{
    796 			// Reset STA, STO, SI
    797 	       		I2Cx->I2CONCLR = I2C_I2CONCLR_SIC|I2C_I2CONCLR_STOC|I2C_I2CONCLR_STAC;
    798 	       		I2Cx->I2CONSET = I2C_I2CONSET_STA;
    799 	       		return;
    800 		}
    801 	}
    802 	else if (Ret & I2C_RECV_END) 
    803 	{
    804 		goto s_int_end;
    805 	}
    806 	else
    807 	{
    808 		return;
    809 	}
    810 
    811 s_int_end:
    812 	// Disable interrupt
    813 	I2C_IntCmd(I2Cx, FALSE);
    814 
    815 	I2Cx->I2CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC;
    816 
    817 	I2C_MasterComplete[i2cId] = TRUE;
    818 		
    819 }
    820 
    821 
    822 /*********************************************************************//**
    823  * @brief 		General Slave Interrupt handler for I2C peripheral
    824  * @param[in]	I2Cx	I2C peripheral selected, should be:
    825  *  			- LPC_I2C0
    826  *  			- LPC_I2C1
    827  *  			- LPC_I2C2
    828  * @return 		None
    829  **********************************************************************/
    830 void I2C_SlaveHandler (LPC_I2C_TypeDef  *I2Cx)
    831 {
    832 	uint32_t i2cId = I2C_getNum(I2Cx);
    833 	uint8_t returnCode;
    834 	I2C_S_SETUP_Type *txrx_setup;
    835 	uint32_t timeout;
    836 	int32_t Ret = I2C_OK;
    837 
    838 	txrx_setup = (I2C_S_SETUP_Type *) i2cdat[i2cId].txrx_setup;
    839 
    840 handle_state:
    841 
    842 	returnCode = (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK);
    843 	// Save current status
    844 	txrx_setup->status = returnCode;
    845 
    846 
    847 	Ret = I2C_SlaveHanleStates(I2Cx, returnCode, txrx_setup);
    848 
    849 	if(I2C_CheckError(Ret))
    850 	{
    851 		goto s_int_end;
    852 	}
    853 	else if (Ret & I2C_STA_STO_RECV)
    854 	{
    855 		// Temporally lock the interrupt for timeout condition
    856 		I2C_IntCmd(I2Cx, FALSE);
    857 		// enable time out
    858 		timeout = I2C_SLAVE_TIME_OUT;
    859 		while(1)
    860 		{
    861 			if (I2Cx->I2CONSET & I2C_I2CONSET_SI)
    862 			{
    863 				// re-Enable interrupt
    864 				I2C_IntCmd(I2Cx, TRUE);
    865 				goto handle_state;
    866 			}
    867 			else
    868 			{
    869 				timeout--;
    870 				if (timeout == 0)
    871 				{
    872 					// timeout occur, it's really a stop condition
    873 					txrx_setup->status |= I2C_SETUP_STATUS_DONE;
    874 					goto s_int_end;
    875 				}
    876 			}
    877 		}	
    878 	}
    879 	else if(Ret &I2C_SEND_END)
    880 	{
    881 		goto s_int_end;
    882 	}
    883 	else
    884 	{
    885 		return;
    886 	}
    887 
    888 s_int_end:
    889 	// Disable interrupt
    890 	I2C_IntCmd(I2Cx, FALSE);
    891 	I2Cx->I2CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC;
    892 
    893 	I2C_SlaveComplete[i2cId] = TRUE;
    894 }
    895 
    896 /*********************************************************************//**
    897  * @brief 		Transmit and Receive data in master mode
    898  * @param[in]	I2Cx			I2C peripheral selected, should be:
    899  *  			- LPC_I2C0
    900  * 				- LPC_I2C1
    901  * 				- LPC_I2C2
    902  * @param[in]	TransferCfg		Pointer to a I2C_M_SETUP_Type structure that
    903  * 								contains specified information about the
    904  * 								configuration for master transfer.
    905  * @param[in]	Opt				a I2C_TRANSFER_OPT_Type type that selected for
    906  * 								interrupt or polling mode.
    907  * @return 		SUCCESS or ERROR
    908  *
    909  * Note:
    910  * - In case of using I2C to transmit data only, either transmit length set to 0
    911  * or transmit data pointer set to NULL.
    912  * - In case of using I2C to receive data only, either receive length set to 0
    913  * or receive data pointer set to NULL.
    914  * - In case of using I2C to transmit followed by receive data, transmit length,
    915  * transmit data pointer, receive length and receive data pointer should be set
    916  * corresponding.
    917  **********************************************************************/
    918 Status I2C_MasterTransferData(LPC_I2C_TypeDef *I2Cx, I2C_M_SETUP_Type *TransferCfg, \
    919 																	I2C_TRANSFER_OPT_Type Opt)
    920 {
    921 	uint32_t i2cId = I2C_getNum(I2Cx);	uint32_t CodeStatus;
    922 	int32_t Ret = I2C_OK;
    923 
    924 	// Reset I2C setup value to default state
    925 	TransferCfg->tx_count = 0;
    926 	TransferCfg->rx_count = 0;
    927 	TransferCfg->status = 0;
    928 
    929 	if (Opt == I2C_TRANSFER_POLLING)
    930 	{
    931 		/* First Start condition -------------------------------------------------------------- */
    932 		TransferCfg->retransmissions_count = 0;
    933 retry:
    934 		// Reset I2C setup value to default state
    935 		TransferCfg->tx_count = 0;
    936 		TransferCfg->rx_count = 0;
    937 
    938 		// Start command
    939 		CodeStatus = I2C_Start(I2Cx);
    940 		
    941 		while(1)	// send data first and then receive data from Slave.
    942 		{
    943 			Ret = I2C_MasterHanleStates(I2Cx, CodeStatus, TransferCfg);
    944 			if(I2C_CheckError(Ret))
    945 			{
    946 				TransferCfg->retransmissions_count++;
    947 				if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){
    948 						// save status
    949 						TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_NOACKF;
    950 						goto error;
    951 					} else {
    952 						goto retry;
    953 					}
    954 			}
    955 			else if( (Ret & I2C_BYTE_SENT) ||
    956 					(Ret & I2C_BYTE_RECV))
    957 			{
    958 				// Wait for sending ends				
    959 				while (!(I2Cx->I2CONSET & I2C_I2CONSET_SI));
    960 			}
    961 			else if (Ret & I2C_SEND_END) // already send all data
    962 			{
    963 				// If no need to wait for data from Slave
    964 				if(TransferCfg->rx_count >= (TransferCfg->rx_length)) 
    965 				{
    966 					break;
    967 				}
    968 				else
    969 				{
    970 					I2C_Start(I2Cx);
    971 				}
    972 			}
    973 			else if (Ret & I2C_RECV_END) // already receive all data
    974 			{
    975 				break;
    976 			}
    977              		CodeStatus = I2Cx->I2STAT & I2C_STAT_CODE_BITMASK;
    978 		}
    979 		return SUCCESS;
    980 error:
    981 		return ERROR;
    982 	}
    983 
    984 	else if (Opt == I2C_TRANSFER_INTERRUPT)
    985 	{
    986 		// Setup tx_rx data, callback and interrupt handler
    987 		i2cdat[i2cId].txrx_setup = (uint32_t) TransferCfg;
    988 
    989 		// Set direction phase, write first
    990 		i2cdat[i2cId].dir = 0;
    991 
    992 		/* First Start condition -------------------------------------------------------------- */
    993 		// Reset STA, STO, SI
    994 		I2Cx->I2CONCLR = I2C_I2CONCLR_SIC|I2C_I2CONCLR_STOC|I2C_I2CONCLR_STAC;
    995 		I2Cx->I2CONSET = I2C_I2CONSET_STA;
    996 
    997 		I2C_IntCmd(I2Cx, TRUE);
    998 
    999 		return (SUCCESS);
   1000 	}
   1001 
   1002 	return ERROR;
   1003 }
   1004 
   1005 /*********************************************************************//**
   1006  * @brief 		Receive and Transmit data in slave mode
   1007  * @param[in]	I2Cx			I2C peripheral selected, should be
   1008  *    			- LPC_I2C0
   1009  * 				- LPC_I2C1
   1010  * 				- LPC_I2C2
   1011  * @param[in]	TransferCfg		Pointer to a I2C_S_SETUP_Type structure that
   1012  * 								contains specified information about the
   1013  * 								configuration for master transfer.
   1014  * @param[in]	Opt				I2C_TRANSFER_OPT_Type type that selected for
   1015  * 								interrupt or polling mode.
   1016  * @return 		SUCCESS or ERROR
   1017  *
   1018  * Note:
   1019  * The mode of slave's operation depends on the command sent from master on
   1020  * the I2C bus. If the master send a SLA+W command, this sub-routine will
   1021  * use receive data length and receive data pointer. If the master send a SLA+R
   1022  * command, this sub-routine will use transmit data length and transmit data
   1023  * pointer.
   1024  * If the master issue an repeat start command or a stop command, the slave will
   1025  * enable an time out condition, during time out condition, if there's no activity
   1026  * on I2C bus, the slave will exit, otherwise (i.e. the master send a SLA+R/W),
   1027  * the slave then switch to relevant operation mode. The time out should be used
   1028  * because the return status code can not show difference from stop and repeat
   1029  * start command in slave operation.
   1030  * In case of the expected data length from master is greater than data length
   1031  * that slave can support:
   1032  * - In case of reading operation (from master): slave will return I2C_I2DAT_IDLE_CHAR
   1033  * value.
   1034  * - In case of writing operation (from master): slave will ignore remain data from master.
   1035  **********************************************************************/
   1036 Status I2C_SlaveTransferData(LPC_I2C_TypeDef *I2Cx, I2C_S_SETUP_Type *TransferCfg, \
   1037 								I2C_TRANSFER_OPT_Type Opt)
   1038 {
   1039 	int32_t   Ret = I2C_OK;
   1040 	
   1041 	uint32_t CodeStatus;
   1042 	uint32_t timeout;
   1043 	int32_t time_en;
   1044 	uint32_t i2cId = I2C_getNum(I2Cx);
   1045 	// Reset I2C setup value to default state
   1046 	TransferCfg->tx_count = 0;
   1047 	TransferCfg->rx_count = 0;
   1048 	TransferCfg->status = 0;
   1049 
   1050 	// Polling option
   1051 	if (Opt == I2C_TRANSFER_POLLING)
   1052 	{
   1053 		/* Set AA bit to ACK command on I2C bus */
   1054 		I2Cx->I2CONSET = I2C_I2CONSET_AA;
   1055 		
   1056 		/* Clear SI bit to be ready ... */
   1057 		I2Cx->I2CONCLR = (I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC|I2C_I2CONCLR_STOC);
   1058 
   1059 		time_en = 0;
   1060 		timeout = 0;
   1061 
   1062 		while (1)
   1063 		{
   1064 			/* Check SI flag ready */
   1065 			if (I2Cx->I2CONSET & I2C_I2CONSET_SI)
   1066 			{
   1067 				time_en = 0;
   1068 
   1069 				CodeStatus = (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK);
   1070 
   1071 				Ret = I2C_SlaveHanleStates(I2Cx, CodeStatus, TransferCfg);
   1072 				if(I2C_CheckError(Ret))
   1073 				{
   1074 					goto s_error;
   1075 				}
   1076 				else if(Ret & I2C_STA_STO_RECV)
   1077 				{
   1078 					time_en = 1;
   1079 					timeout = 0;
   1080 				}
   1081                 else if (Ret & I2C_SEND_END)
   1082                 {
   1083                     goto s_end_stage;
   1084                 }
   1085 			}
   1086 			else if (time_en)
   1087 			{
   1088 				if (timeout++ > I2C_SLAVE_TIME_OUT)
   1089 				{
   1090 					// it's really a stop condition, goto end stage
   1091 					goto s_end_stage;
   1092 				}
   1093 			}
   1094 		}
   1095 
   1096 s_end_stage:
   1097 		/* Clear AA bit to disable ACK on I2C bus */
   1098 		I2Cx->I2CONCLR = I2C_I2CONCLR_AAC;
   1099 
   1100 		// Check if there's no error during operation
   1101 		// Update status
   1102 		TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_DONE;
   1103 		return SUCCESS;
   1104 
   1105 s_error:
   1106 		/* Clear AA bit to disable ACK on I2C bus */
   1107 		I2Cx->I2CONCLR = I2C_I2CONCLR_AAC;
   1108 
   1109 		// Update status
   1110 		TransferCfg->status = CodeStatus;
   1111 		return ERROR;
   1112 	}
   1113 
   1114 	else if (Opt == I2C_TRANSFER_INTERRUPT)
   1115 	{
   1116 		// Setup tx_rx data, callback and interrupt handler
   1117 		i2cdat[i2cId].txrx_setup = (uint32_t) TransferCfg;
   1118 
   1119 		// Set direction phase, read first
   1120 		i2cdat[i2cId].dir = 1;
   1121 
   1122 		// Enable AA
   1123 		I2Cx->I2CONSET = I2C_I2CONSET_AA;
   1124 		I2Cx->I2CONCLR = I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC;
   1125 		I2C_IntCmd(I2Cx, TRUE);
   1126 
   1127 		return (SUCCESS);
   1128 	}
   1129 
   1130 	return ERROR;
   1131 }
   1132 
   1133 /*********************************************************************//**
   1134  * @brief		Set Own slave address in I2C peripheral corresponding to
   1135  * 				parameter specified in OwnSlaveAddrConfigStruct.
   1136  * @param[in]	I2Cx	I2C peripheral selected, should be
   1137  *    			- LPC_I2C0
   1138  * 				- LPC_I2C1
   1139  * 				- LPC_I2C2
   1140  * @param[in]	OwnSlaveAddrConfigStruct	Pointer to a I2C_OWNSLAVEADDR_CFG_Type
   1141  * 				structure that contains the configuration information for the
   1142 *               specified I2C slave address.
   1143  * @return 		None
   1144  **********************************************************************/
   1145 void I2C_SetOwnSlaveAddr(LPC_I2C_TypeDef *I2Cx, I2C_OWNSLAVEADDR_CFG_Type *OwnSlaveAddrConfigStruct)
   1146 {
   1147 	uint32_t tmp;
   1148 	CHECK_PARAM(PARAM_I2Cx(I2Cx));
   1149 	CHECK_PARAM(PARAM_I2C_SLAVEADDR_CH(OwnSlaveAddrConfigStruct->SlaveAddrChannel));
   1150 	CHECK_PARAM(PARAM_FUNCTIONALSTATE(OwnSlaveAddrConfigStruct->GeneralCallState));
   1151 
   1152 	tmp = (((uint32_t)(OwnSlaveAddrConfigStruct->SlaveAddr_7bit << 1)) \
   1153 			| ((OwnSlaveAddrConfigStruct->GeneralCallState == ENABLE) ? 0x01 : 0x00))& I2C_I2ADR_BITMASK;
   1154 	switch (OwnSlaveAddrConfigStruct->SlaveAddrChannel)
   1155 	{
   1156 	case 0:
   1157 		I2Cx->I2ADR0 = tmp;
   1158 		I2Cx->I2MASK0 = I2C_I2MASK_MASK((uint32_t) \
   1159 				(OwnSlaveAddrConfigStruct->SlaveAddrMaskValue));
   1160 		break;
   1161 	case 1:
   1162 		I2Cx->I2ADR1 = tmp;
   1163 		I2Cx->I2MASK1 = I2C_I2MASK_MASK((uint32_t) \
   1164 				(OwnSlaveAddrConfigStruct->SlaveAddrMaskValue));
   1165 		break;
   1166 	case 2:
   1167 		I2Cx->I2ADR2 = tmp;
   1168 		I2Cx->I2MASK2 = I2C_I2MASK_MASK((uint32_t) \
   1169 				(OwnSlaveAddrConfigStruct->SlaveAddrMaskValue));
   1170 		break;
   1171 	case 3:
   1172 		I2Cx->I2ADR3 = tmp;
   1173 		I2Cx->I2MASK3 = I2C_I2MASK_MASK((uint32_t) \
   1174 				(OwnSlaveAddrConfigStruct->SlaveAddrMaskValue));
   1175 		break;
   1176 	}
   1177 }
   1178 
   1179 
   1180 /*********************************************************************//**
   1181  * @brief		Configures functionality in I2C monitor mode
   1182  * @param[in]	I2Cx	I2C peripheral selected, should be
   1183  *   			- LPC_I2C0
   1184  * 				- LPC_I2C1
   1185  * 				- LPC_I2C2
   1186  * @param[in]	MonitorCfgType Monitor Configuration type, should be:
   1187  * 				- I2C_MONITOR_CFG_SCL_OUTPUT: I2C module can 'stretch'
   1188  * 				the clock line (hold it low) until it has had time to
   1189  * 				respond to an I2C interrupt.
   1190  * 				- I2C_MONITOR_CFG_MATCHALL: When this bit is set to '1'
   1191  * 				and the I2C is in monitor mode, an interrupt will be
   1192  * 				generated on ANY address received.
   1193  * @param[in]	NewState New State of this function, should be:
   1194  * 				- ENABLE: Enable this function.
   1195  * 				- DISABLE: Disable this function.
   1196  * @return		None
   1197  **********************************************************************/
   1198 void I2C_MonitorModeConfig(LPC_I2C_TypeDef *I2Cx, uint32_t MonitorCfgType, FunctionalState NewState)
   1199 {
   1200 	CHECK_PARAM(PARAM_I2Cx(I2Cx));
   1201 	CHECK_PARAM(PARAM_I2C_MONITOR_CFG(MonitorCfgType));
   1202 	CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
   1203 
   1204 	if (NewState == ENABLE)
   1205 	{
   1206 		I2Cx->MMCTRL |= MonitorCfgType;
   1207 	}
   1208 	else
   1209 	{
   1210 		I2Cx->MMCTRL &= (~MonitorCfgType) & I2C_I2MMCTRL_BITMASK;
   1211 	}
   1212 }
   1213 
   1214 
   1215 /*********************************************************************//**
   1216  * @brief		Enable/Disable I2C monitor mode
   1217  * @param[in]	I2Cx	I2C peripheral selected, should be
   1218  *    			- LPC_I2C0
   1219  * 				- LPC_I2C1
   1220  * 				- LPC_I2C2
   1221  * @param[in]	NewState New State of this function, should be:
   1222  * 				- ENABLE: Enable monitor mode.
   1223  * 				- DISABLE: Disable monitor mode.
   1224  * @return		None
   1225  **********************************************************************/
   1226 void I2C_MonitorModeCmd(LPC_I2C_TypeDef *I2Cx, FunctionalState NewState)
   1227 {
   1228 	CHECK_PARAM(PARAM_I2Cx(I2Cx));
   1229 	CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
   1230 
   1231 	if (NewState == ENABLE)
   1232 	{
   1233 		I2Cx->MMCTRL |= I2C_I2MMCTRL_MM_ENA;
   1234 		I2Cx->I2CONSET = I2C_I2CONSET_AA;
   1235 		I2Cx->I2CONCLR = I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC;
   1236 	}
   1237 	else
   1238 	{
   1239 		I2Cx->MMCTRL &= (~I2C_I2MMCTRL_MM_ENA) & I2C_I2MMCTRL_BITMASK;
   1240 		I2Cx->I2CONCLR = I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC | I2C_I2CONCLR_AAC;
   1241 	}
   1242 	I2C_MonitorBufferIndex = 0;
   1243 }
   1244 
   1245 
   1246 /*********************************************************************//**
   1247  * @brief		Get data from I2C data buffer in monitor mode.
   1248  * @param[in]	I2Cx	I2C peripheral selected, should be
   1249  *    			- LPC_I2C0
   1250  * 				- LPC_I2C1
   1251  * 				- LPC_I2C2
   1252  * @return		None
   1253  * Note:	In monitor mode, the I2C module may lose the ability to stretch
   1254  * the clock (stall the bus) if the ENA_SCL bit is not set. This means that
   1255  * the processor will have a limited amount of time to read the contents of
   1256  * the data received on the bus. If the processor reads the I2DAT shift
   1257  * register, as it ordinarily would, it could have only one bit-time to
   1258  * respond to the interrupt before the received data is overwritten by
   1259  * new data.
   1260  **********************************************************************/
   1261 uint8_t I2C_MonitorGetDatabuffer(LPC_I2C_TypeDef *I2Cx)
   1262 {
   1263 	CHECK_PARAM(PARAM_I2Cx(I2Cx));
   1264 	return ((uint8_t)(I2Cx->I2DATA_BUFFER));
   1265 }
   1266 
   1267 /*********************************************************************//**
   1268  * @brief		Get data from I2C data buffer in monitor mode.
   1269  * @param[in]	I2Cx	I2C peripheral selected, should be
   1270  *    			- LPC_I2C0
   1271  * 				- LPC_I2C1
   1272  * 				- LPC_I2C2
   1273  * @return		None
   1274  * Note:	In monitor mode, the I2C module may lose the ability to stretch
   1275  * the clock (stall the bus) if the ENA_SCL bit is not set. This means that
   1276  * the processor will have a limited amount of time to read the contents of
   1277  * the data received on the bus. If the processor reads the I2DAT shift
   1278  * register, as it ordinarily would, it could have only one bit-time to
   1279  * respond to the interrupt before the received data is overwritten by
   1280  * new data.
   1281  **********************************************************************/
   1282 BOOL_8 I2C_MonitorHandler(LPC_I2C_TypeDef *I2Cx, uint8_t *buffer, uint32_t size)
   1283 {
   1284 	BOOL_8 ret=FALSE;
   1285 
   1286 	I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;
   1287 
   1288 	buffer[I2C_MonitorBufferIndex] = (uint8_t)(I2Cx->I2DATA_BUFFER);
   1289 	I2C_MonitorBufferIndex++;
   1290 	if(I2C_MonitorBufferIndex >= size)
   1291 	{
   1292 		ret = TRUE;
   1293 	}
   1294 	return ret;
   1295 }
   1296 /*********************************************************************//**
   1297  * @brief 		Get status of Master Transfer
   1298  * @param[in]	I2Cx	I2C peripheral selected, should be:
   1299  *  			- LPC_I2C0
   1300  * 				- LPC_I2C1
   1301  * 				- LPC_I2C2
   1302  * @return 		Master transfer status, could be:
   1303  * 				- TRUE	master transfer completed
   1304  * 				- FALSE master transfer have not completed yet
   1305  **********************************************************************/
   1306 uint32_t I2C_MasterTransferComplete(LPC_I2C_TypeDef *I2Cx)
   1307 {
   1308 	uint32_t retval, tmp;
   1309 	tmp = I2C_getNum(I2Cx);
   1310 	retval = I2C_MasterComplete[tmp];
   1311 	I2C_MasterComplete[tmp] = FALSE;
   1312 	return retval;
   1313 }
   1314 
   1315 /*********************************************************************//**
   1316  * @brief 		Get status of Slave Transfer
   1317  * @param[in]	I2Cx	I2C peripheral selected, should be:
   1318  * 				- LPC_I2C0
   1319  * 				- LPC_I2C1
   1320  * 				- LPC_I2C2
   1321  * @return 		Complete status, could be: TRUE/FALSE
   1322  **********************************************************************/
   1323 uint32_t I2C_SlaveTransferComplete(LPC_I2C_TypeDef *I2Cx)
   1324 {
   1325 	uint32_t retval, tmp;
   1326 	tmp = I2C_getNum(I2Cx);
   1327 	retval = I2C_SlaveComplete[tmp];
   1328 	I2C_SlaveComplete[tmp] = FALSE;
   1329 	return retval;
   1330 }
   1331 
   1332 
   1333 
   1334 /**
   1335  * @}
   1336  */
   1337 
   1338 #endif /* _I2C */
   1339 
   1340 /**
   1341  * @}
   1342  */
   1343 
   1344 /* --------------------------------- End Of File ------------------------------ */