1 /**********************************************************************
\r
2 * $Id$ lpc43xx_i2c.c 2011-06-02
\r
4 * @file lpc43xx_i2c.c
\r
5 * @brief Contains all functions support for I2C firmware library
\r
8 * @date 02. June. 2011
\r
9 * @author NXP MCU SW Application Team
\r
11 * Copyright(C) 2011, NXP Semiconductor
\r
12 * All rights reserved.
\r
14 ***********************************************************************
\r
15 * Software that is described herein is for illustrative purposes only
\r
16 * which provides customers with programming information regarding the
\r
17 * products. This software is supplied "AS IS" without any warranties.
\r
18 * NXP Semiconductors assumes no responsibility or liability for the
\r
19 * use of the software, conveys no license or title under any patent,
\r
20 * copyright, or mask work right to the product. NXP Semiconductors
\r
21 * reserves the right to make changes in the software without
\r
22 * notification. NXP Semiconductors also make no representation or
\r
23 * warranty that such application will be suitable for the specified
\r
24 * use without further testing or modification.
\r
25 **********************************************************************/
\r
27 /* Peripheral group ----------------------------------------------------------- */
\r
32 /* Includes ------------------------------------------------------------------- */
\r
33 #include "lpc43xx_i2c.h"
\r
34 #include "lpc43xx_cgu.h"
\r
37 #define MD_EZI (0x1<<6)
\r
38 #define MD_ZI (0x1<<7)
\r
40 /* If this source file built with example, the lpc43xx FW library configuration
\r
41 * file in each example directory ("lpc43xx_libcfg.h") must be included,
\r
42 * otherwise the default FW library configuration file must be included instead
\r
44 #ifdef __BUILD_WITH_EXAMPLE__
\r
45 #include "lpc43xx_libcfg.h"
\r
47 #include "lpc43xx_libcfg_default.h"
\r
48 #endif /* __BUILD_WITH_EXAMPLE__ */
\r
54 /* Private Types -------------------------------------------------------------- */
\r
55 /** @defgroup I2C_Private_Types I2C Private Types
\r
58 #define SFSP2_3_CONFIGURE_I2C1_SDA (0x00000001 | MD_ZI | MD_EZI)
\r
59 #define SFSP2_4_CONFIGURE_I2C1_SCL (0x00000001 | MD_ZI | MD_EZI)
\r
60 #define SFSI2C0_CONFIGURE_STANDARD_FAST_MODE (1<<3 | 1<<11)
\r
61 #define SFSI2C0_CONFIGURE_FASTPLUS_HIGHSPEED_MODE (2<<1 | 1<<3 | 1<<7 | 1<<10 | 1<<11)
\r
64 * @brief I2C device configuration structure type
\r
68 uint32_t txrx_setup; /* Transmission setup */
\r
69 int32_t dir; /* Current direction phase, 0 - write, 1 - read */
\r
76 /* Private Variables ---------------------------------------------------------- */
\r
78 * @brief II2C driver data for I2C0, I2C1
\r
80 static I2C_CFG_T i2cdat[3];
\r
82 static uint32_t I2C_MasterComplete[3];
\r
83 static uint32_t I2C_SlaveComplete[3];
\r
85 static uint32_t I2C_MonitorBufferIndex;
\r
87 /* Private Functions ---------------------------------------------------------- */
\r
89 /* Get I2C number */
\r
90 static int32_t I2C_getNum(LPC_I2Cn_Type *I2Cx);
\r
92 /* Generate a start condition on I2C bus (in master mode only) */
\r
93 static uint32_t I2C_Start (LPC_I2Cn_Type *I2Cx);
\r
95 /* Generate a stop condition on I2C bus (in master mode only) */
\r
96 static void I2C_Stop (LPC_I2Cn_Type *I2Cx);
\r
98 /* I2C send byte subroutine */
\r
99 static uint32_t I2C_SendByte (LPC_I2Cn_Type *I2Cx, uint8_t databyte);
\r
101 /* I2C get byte subroutine */
\r
102 static uint32_t I2C_GetByte (LPC_I2Cn_Type *I2Cx, uint8_t *retdat, Bool ack);
\r
104 /*--------------------------------------------------------------------------------*/
\r
105 /********************************************************************//**
\r
106 * @brief Convert from I2C peripheral to number
\r
107 * @param[in] I2Cx I2C peripheral selected, should be:
\r
108 * - LPC_I2C0 :I2C0 peripheral
\r
109 * - LPC_I2C1 :I2C1 peripheral
\r
110 * @return I2C number or error code, could be:
\r
114 *********************************************************************/
\r
115 static int32_t I2C_getNum(LPC_I2Cn_Type *I2Cx){
\r
116 if (I2Cx == LPC_I2C0) {
\r
118 } else if (I2Cx == LPC_I2C1) {
\r
125 /********************************************************************//**
\r
126 * @brief Generate a start condition on I2C bus (in master mode only)
\r
127 * @param[in] I2Cx I2C peripheral selected, should be:
\r
128 * - LPC_I2C0 :I2C0 peripheral
\r
129 * - LPC_I2C1 :I2C1 peripheral
\r
130 * @return value of I2C status register after generate a start condition
\r
131 *********************************************************************/
\r
132 static uint32_t I2C_Start (LPC_I2Cn_Type *I2Cx)
\r
134 I2Cx->CONSET = I2C_I2CONSET_STA;
\r
135 I2Cx->CONCLR = I2C_I2CONCLR_SIC;
\r
137 // Wait for complete
\r
138 while (!(I2Cx->CONSET & I2C_I2CONSET_SI));
\r
139 I2Cx->CONCLR = I2C_I2CONCLR_STAC;
\r
140 return (I2Cx->STAT & I2C_STAT_CODE_BITMASK);
\r
144 /********************************************************************//**
\r
145 * @brief Generate a stop condition on I2C bus (in master mode only)
\r
146 * @param[in] I2Cx I2C peripheral selected, should be:
\r
147 * - LPC_I2C0 :I2C0 peripheral
\r
148 * - LPC_I2C1 :I2C1 peripheral
\r
150 *********************************************************************/
\r
151 static void I2C_Stop (LPC_I2Cn_Type *I2Cx)
\r
154 /* Make sure start bit is not active */
\r
155 if (I2Cx->CONSET & I2C_I2CONSET_STA)
\r
157 I2Cx->CONCLR = I2C_I2CONCLR_STAC;
\r
159 I2Cx->CONSET = I2C_I2CONSET_STO;
\r
160 I2Cx->CONCLR = I2C_I2CONCLR_SIC;
\r
164 /********************************************************************//**
\r
165 * @brief Send a byte
\r
166 * @param[in] I2Cx I2C peripheral selected, should be:
\r
167 * - LPC_I2C0 :I2C0 peripheral
\r
168 * - LPC_I2C1 :I2C1 peripheral
\r
169 * @param[in] databyte sent data
\r
170 * @return value of I2C status register after sending
\r
171 *********************************************************************/
\r
172 static uint32_t I2C_SendByte (LPC_I2Cn_Type *I2Cx, uint8_t databyte)
\r
174 /* Make sure start bit is not active */
\r
175 if (I2Cx->CONSET & I2C_I2CONSET_STA)
\r
177 I2Cx->CONCLR = I2C_I2CONCLR_STAC;
\r
179 I2Cx->DAT = databyte & I2C_I2DAT_BITMASK;
\r
180 I2Cx->CONCLR = I2C_I2CONCLR_SIC;
\r
182 while (!(I2Cx->CONSET & I2C_I2CONSET_SI));
\r
183 return (I2Cx->STAT & I2C_STAT_CODE_BITMASK);
\r
187 /********************************************************************//**
\r
188 * @brief Get a byte
\r
189 * @param[in] I2Cx I2C peripheral selected, should be:
\r
190 * - LPC_I2C0 :I2C0 peripheral
\r
191 * - LPC_I2C1 :I2C1 peripheral
\r
192 * @param[out] retdat pointer to return data
\r
193 * @param[in] ack assert acknowledge or not, should be: TRUE/FALSE
\r
194 * @return value of I2C status register after sending
\r
195 *********************************************************************/
\r
196 static uint32_t I2C_GetByte (LPC_I2Cn_Type *I2Cx, uint8_t *retdat, Bool ack)
\r
200 I2Cx->CONSET = I2C_I2CONSET_AA;
\r
204 I2Cx->CONCLR = I2C_I2CONCLR_AAC;
\r
206 I2Cx->CONCLR = I2C_I2CONCLR_SIC;
\r
208 while (!(I2Cx->CONSET & I2C_I2CONSET_SI));
\r
209 *retdat = (uint8_t) (I2Cx->DAT & I2C_I2DAT_BITMASK);
\r
210 return (I2Cx->STAT & I2C_STAT_CODE_BITMASK);
\r
213 /* End of Private Functions --------------------------------------------------- */
\r
216 /* Public Functions ----------------------------------------------------------- */
\r
217 /** @addtogroup I2C_Public_Functions
\r
221 /********************************************************************//**
\r
222 * @brief Initializes the I2Cx peripheral with specified parameter.
\r
223 * @param[in] I2Cx I2C peripheral selected, should be
\r
224 * - LPC_I2C0 :I2C0 peripheral
\r
225 * - LPC_I2C1 :I2C1 peripheral
\r
226 * @param[in] clockrate Target clock rate value to initialized I2C
\r
229 *********************************************************************/
\r
230 void I2C_Init(LPC_I2Cn_Type *I2Cx, uint32_t clockrate)
\r
234 CHECK_PARAM(PARAM_I2Cx(I2Cx));
\r
236 if (I2Cx==LPC_I2C0)
\r
238 /* Set up clock for I2C0 module */
\r
239 //LPC_CGU->BASE_VPB1_CLK = (SRC_PL160M_0<<24) | (1<<11);
\r
240 CGU_EntityConnect(CGU_CLKSRC_PLL1, CGU_BASE_APB1);
\r
241 /* Select weather standard, fast, fast plus mode*/
\r
242 if(clockrate>=1000000)// Fast mode plus: 1MHz, high speed 3.4MHz
\r
243 LPC_SCU->SFSI2C0 = SFSI2C0_CONFIGURE_FASTPLUS_HIGHSPEED_MODE;
\r
244 else // standard 100KHz, fast 400KHz
\r
245 LPC_SCU->SFSI2C0 = SFSI2C0_CONFIGURE_STANDARD_FAST_MODE;
\r
247 else if (I2Cx==LPC_I2C1)
\r
249 /* Set up clock for I2C1 module */
\r
250 //LPC_CGU->BASE_VPB3_CLK = (SRC_PL160M_0<<24) | (1<<11);
\r
251 CGU_EntityConnect(CGU_CLKSRC_PLL1, CGU_BASE_APB3);
\r
252 /* Configure pin function for I2C1*/
\r
253 LPC_SCU->SFSP2_3 = SFSP2_3_CONFIGURE_I2C1_SDA; /* SDA */
\r
254 LPC_SCU->SFSP2_4 = SFSP2_4_CONFIGURE_I2C1_SCL; /* SCL */
\r
255 /* Check if I2C1 run fast mode*/
\r
256 if(clockrate != 400000)
\r
260 // Up-Support this device
\r
264 /* Set clock rate */
\r
265 if(clockrate<1000) //make sure SCLH,SCLL not exceed its 16bit value
\r
267 tem = CGU_GetPCLKFrequency(CGU_PERIPHERAL_M3CORE) / clockrate;
\r
268 I2Cx->SCLH = (uint32_t)(tem / 2);
\r
269 I2Cx->SCLL = (uint32_t)(tem - I2Cx->SCLH);
\r
270 /* Set I2C operation to default */
\r
271 I2Cx->CONCLR = (I2C_I2CONCLR_AAC |I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC | I2C_I2CONCLR_I2ENC);
\r
275 /*********************************************************************//**
\r
276 * @brief De-initializes the I2C peripheral registers to their
\r
277 * default reset values.
\r
278 * @param[in] I2Cx I2C peripheral selected, should be
\r
279 * - LPC_I2C0 :I2C0 peripheral
\r
280 * - LPC_I2C1 :I2C1 peripheral
\r
282 **********************************************************************/
\r
283 void I2C_DeInit(LPC_I2Cn_Type* I2Cx)
\r
285 CHECK_PARAM(PARAM_I2Cx(I2Cx));
\r
287 /* Disable I2C control */
\r
288 I2Cx->CONCLR = I2C_I2CONCLR_I2ENC;
\r
293 /*********************************************************************//**
\r
294 * @brief Enable or disable I2C peripheral's operation
\r
295 * @param[in] I2Cx I2C peripheral selected, should be
\r
296 * - LPC_I2C0 :I2C0 peripheral
\r
297 * - LPC_I2C1 :I2C1 peripheral
\r
298 * @param[in] NewState New State of I2Cx peripheral's operation, should be:
\r
299 * - ENABLE :enable I2C operation
\r
300 * - DISABLE :disable I2C operation
\r
302 **********************************************************************/
\r
303 void I2C_Cmd(LPC_I2Cn_Type* I2Cx, FunctionalState NewState)
\r
305 CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
\r
306 CHECK_PARAM(PARAM_I2Cx(I2Cx));
\r
308 if (NewState == ENABLE)
\r
310 I2Cx->CONSET = I2C_I2CONSET_I2EN;
\r
314 I2Cx->CONCLR = I2C_I2CONCLR_I2ENC;
\r
319 /*********************************************************************//**
\r
320 * @brief Enable/Disable interrupt for I2C peripheral
\r
321 * @param[in] I2Cx I2C peripheral selected, should be:
\r
322 * - LPC_I2C0 :I2C0 peripheral
\r
323 * - LPC_I2C1 :I2C1 peripheral
\r
324 * @param[in] NewState New State of I2C peripheral interrupt in NVIC core
\r
326 * - ENABLE: enable interrupt for this I2C peripheral
\r
327 * - DISABLE: disable interrupt for this I2C peripheral
\r
329 **********************************************************************/
\r
330 void I2C_IntCmd (LPC_I2Cn_Type *I2Cx, Bool NewState)
\r
334 if(I2Cx == LPC_I2C0)
\r
336 NVIC_EnableIRQ(I2C0_IRQn);
\r
338 else if (I2Cx == LPC_I2C1)
\r
340 NVIC_EnableIRQ(I2C1_IRQn);
\r
345 if(I2Cx == LPC_I2C0)
\r
347 NVIC_DisableIRQ(I2C0_IRQn);
\r
349 else if (I2Cx == LPC_I2C1)
\r
351 NVIC_DisableIRQ(I2C1_IRQn);
\r
358 /*********************************************************************//**
\r
359 * @brief General Master Interrupt handler for I2C peripheral
\r
360 * @param[in] I2Cx I2C peripheral selected, should be:
\r
361 * - LPC_I2C0 :I2C0 peripheral
\r
362 * - LPC_I2C1 :I2C1 peripheral
\r
364 **********************************************************************/
\r
365 void I2C_MasterHandler (LPC_I2Cn_Type *I2Cx)
\r
368 uint8_t returnCode;
\r
369 I2C_M_SETUP_Type *txrx_setup;
\r
371 tmp = I2C_getNum(I2Cx);
\r
372 txrx_setup = (I2C_M_SETUP_Type *) i2cdat[tmp].txrx_setup;
\r
374 returnCode = (I2Cx->STAT & I2C_STAT_CODE_BITMASK);
\r
375 // Save current status
\r
376 txrx_setup->status = returnCode;
\r
377 // there's no relevant information
\r
378 if (returnCode == I2C_I2STAT_NO_INF){
\r
379 I2Cx->CONCLR = I2C_I2CONCLR_SIC;
\r
383 /* ----------------------------- TRANSMIT PHASE --------------------------*/
\r
384 if (i2cdat[tmp].dir == 0){
\r
385 switch (returnCode)
\r
387 /* A start/repeat start condition has been transmitted -------------------*/
\r
388 case I2C_I2STAT_M_TX_START:
\r
389 case I2C_I2STAT_M_TX_RESTART:
\r
390 I2Cx->CONCLR = I2C_I2CONCLR_STAC;
\r
392 * If there's any transmit data, then start to
\r
393 * send SLA+W right now, otherwise check whether if there's
\r
394 * any receive data for next state.
\r
396 if ((txrx_setup->tx_data != NULL) && (txrx_setup->tx_length != 0)){
\r
397 I2Cx->DAT = (txrx_setup->sl_addr7bit << 1);
\r
398 I2Cx->CONCLR = I2C_I2CONCLR_SIC;
\r
404 /* SLA+W has been transmitted, ACK has been received ----------------------*/
\r
405 case I2C_I2STAT_M_TX_SLAW_ACK:
\r
406 /* Data has been transmitted, ACK has been received */
\r
407 case I2C_I2STAT_M_TX_DAT_ACK:
\r
408 /* Send more data */
\r
409 if ((txrx_setup->tx_count < txrx_setup->tx_length) \
\r
410 && (txrx_setup->tx_data != NULL)){
\r
411 I2Cx->DAT = *(uint8_t *)(txrx_setup->tx_data + txrx_setup->tx_count);
\r
412 txrx_setup->tx_count++;
\r
413 I2Cx->CONCLR = I2C_I2CONCLR_SIC;
\r
415 // no more data, switch to next stage
\r
418 // change direction
\r
419 i2cdat[tmp].dir = 1;
\r
420 // Check if any data to receive
\r
421 if ((txrx_setup->rx_length != 0) && (txrx_setup->rx_data != NULL)){
\r
422 // check whether if we need to issue an repeat start
\r
423 if ((txrx_setup->tx_length != 0) && (txrx_setup->tx_data != NULL)){
\r
424 // Send out an repeat start command
\r
425 I2Cx->CONSET = I2C_I2CONSET_STA;
\r
426 I2Cx->CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC;
\r
428 // Don't need issue an repeat start, just goto send SLA+R
\r
433 // no more data send, the go to end stage now
\r
435 // success, goto end stage
\r
436 txrx_setup->status |= I2C_SETUP_STATUS_DONE;
\r
442 /* SLA+W has been transmitted, NACK has been received ----------------------*/
\r
443 case I2C_I2STAT_M_TX_SLAW_NACK:
\r
444 /* Data has been transmitted, NACK has been received -----------------------*/
\r
445 case I2C_I2STAT_M_TX_DAT_NACK:
\r
447 txrx_setup->status |= I2C_SETUP_STATUS_NOACKF;
\r
449 /* Arbitration lost in SLA+R/W or Data bytes -------------------------------*/
\r
450 case I2C_I2STAT_M_TX_ARB_LOST:
\r
452 txrx_setup->status |= I2C_SETUP_STATUS_ARBF;
\r
458 /* ----------------------------- RECEIVE PHASE --------------------------*/
\r
459 else if (i2cdat[tmp].dir == 1){
\r
460 switch (returnCode){
\r
461 /* A start/repeat start condition has been transmitted ---------------------*/
\r
462 case I2C_I2STAT_M_RX_START:
\r
463 case I2C_I2STAT_M_RX_RESTART:
\r
464 I2Cx->CONCLR = I2C_I2CONCLR_STAC;
\r
466 * If there's any receive data, then start to
\r
467 * send SLA+R right now, otherwise check whether if there's
\r
468 * any receive data for end of state.
\r
470 if ((txrx_setup->rx_data != NULL) && (txrx_setup->rx_length != 0)){
\r
472 I2Cx->DAT = (txrx_setup->sl_addr7bit << 1) | 0x01;
\r
473 I2Cx->CONCLR = I2C_I2CONCLR_SIC;
\r
475 // Success, goto end stage
\r
476 txrx_setup->status |= I2C_SETUP_STATUS_DONE;
\r
481 /* SLA+R has been transmitted, ACK has been received -----------------*/
\r
482 case I2C_I2STAT_M_RX_SLAR_ACK:
\r
483 if (txrx_setup->rx_count < (txrx_setup->rx_length - 1)) {
\r
484 /*Data will be received, ACK will be return*/
\r
485 I2Cx->CONSET = I2C_I2CONSET_AA;
\r
488 /*Last data will be received, NACK will be return*/
\r
489 I2Cx->CONCLR = I2C_I2CONSET_AA;
\r
491 I2Cx->CONCLR = I2C_I2CONCLR_SIC;
\r
494 /* Data has been received, ACK has been returned ----------------------*/
\r
495 case I2C_I2STAT_M_RX_DAT_ACK:
\r
496 // Note save data and increase counter first, then check later
\r
498 if ((txrx_setup->rx_data != NULL) && (txrx_setup->rx_count < txrx_setup->rx_length)){
\r
499 *(uint8_t *)(txrx_setup->rx_data + txrx_setup->rx_count) = (I2Cx->DAT & I2C_I2DAT_BITMASK);
\r
500 txrx_setup->rx_count++;
\r
502 if (txrx_setup->rx_count < (txrx_setup->rx_length - 1)) {
\r
503 /*Data will be received, ACK will be return*/
\r
504 I2Cx->CONSET = I2C_I2CONSET_AA;
\r
507 /*Last data will be received, NACK will be return*/
\r
508 I2Cx->CONCLR = I2C_I2CONSET_AA;
\r
511 I2Cx->CONCLR = I2C_I2CONCLR_SIC;
\r
514 /* Data has been received, NACK has been return -------------------------*/
\r
515 case I2C_I2STAT_M_RX_DAT_NACK:
\r
516 /* Save the last data */
\r
517 if ((txrx_setup->rx_data != NULL) && (txrx_setup->rx_count < txrx_setup->rx_length)){
\r
518 *(uint8_t *)(txrx_setup->rx_data + txrx_setup->rx_count) = (I2Cx->DAT & I2C_I2DAT_BITMASK);
\r
519 txrx_setup->rx_count++;
\r
521 // success, go to end stage
\r
522 txrx_setup->status |= I2C_SETUP_STATUS_DONE;
\r
525 /* SLA+R has been transmitted, NACK has been received ------------------*/
\r
526 case I2C_I2STAT_M_RX_SLAR_NACK:
\r
528 txrx_setup->status |= I2C_SETUP_STATUS_NOACKF;
\r
531 /* Arbitration lost ----------------------------------------------------*/
\r
532 case I2C_I2STAT_M_RX_ARB_LOST:
\r
534 txrx_setup->status |= I2C_SETUP_STATUS_ARBF;
\r
537 // check if retransmission is available
\r
538 if (txrx_setup->retransmissions_count < txrx_setup->retransmissions_max){
\r
540 txrx_setup->tx_count = 0;
\r
541 I2Cx->CONSET = I2C_I2CONSET_STA;
\r
542 I2Cx->CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC;
\r
543 txrx_setup->retransmissions_count++;
\r
548 // Disable interrupt
\r
549 I2C_IntCmd(I2Cx, FALSE);
\r
553 I2C_MasterComplete[tmp] = TRUE;
\r
561 /*********************************************************************//**
\r
562 * @brief General Slave Interrupt handler for I2C peripheral
\r
563 * @param[in] I2Cx I2C peripheral selected, should be:
\r
564 * - LPC_I2C0 :I2C0 peripheral
\r
565 * - LPC_I2C1 :I2C1 peripheral
\r
567 **********************************************************************/
\r
568 void I2C_SlaveHandler (LPC_I2Cn_Type *I2Cx)
\r
571 uint8_t returnCode;
\r
572 I2C_S_SETUP_Type *txrx_setup;
\r
575 tmp = I2C_getNum(I2Cx);
\r
576 txrx_setup = (I2C_S_SETUP_Type *) i2cdat[tmp].txrx_setup;
\r
578 returnCode = (I2Cx->STAT & I2C_STAT_CODE_BITMASK);
\r
579 // Save current status
\r
580 txrx_setup->status = returnCode;
\r
581 // there's no relevant information
\r
582 if (returnCode == I2C_I2STAT_NO_INF){
\r
583 I2Cx->CONCLR = I2C_I2CONCLR_SIC;
\r
588 switch (returnCode)
\r
591 /* No status information */
\r
592 case I2C_I2STAT_NO_INF:
\r
593 I2Cx->CONSET = I2C_I2CONSET_AA;
\r
594 I2Cx->CONCLR = I2C_I2CONCLR_SIC;
\r
597 /* Reading phase -------------------------------------------------------- */
\r
598 /* Own SLA+R has been received, ACK has been returned */
\r
599 case I2C_I2STAT_S_RX_SLAW_ACK:
\r
600 /* General call address has been received, ACK has been returned */
\r
601 case I2C_I2STAT_S_RX_GENCALL_ACK:
\r
602 I2Cx->CONSET = I2C_I2CONSET_AA;
\r
603 I2Cx->CONCLR = I2C_I2CONCLR_SIC;
\r
606 /* Previously addressed with own SLA;
\r
607 * DATA byte has been received;
\r
608 * ACK has been returned */
\r
609 case I2C_I2STAT_S_RX_PRE_SLA_DAT_ACK:
\r
610 /* DATA has been received, ACK hasn been return */
\r
611 case I2C_I2STAT_S_RX_PRE_GENCALL_DAT_ACK:
\r
613 * All data bytes that over-flow the specified receive
\r
614 * data length, just ignore them.
\r
616 if ((txrx_setup->rx_count < txrx_setup->rx_length) \
\r
617 && (txrx_setup->rx_data != NULL)){
\r
618 *(uint8_t *)(txrx_setup->rx_data + txrx_setup->rx_count) = (uint8_t)I2Cx->DAT;
\r
619 txrx_setup->rx_count++;
\r
621 I2Cx->CONSET = I2C_I2CONSET_AA;
\r
622 I2Cx->CONCLR = I2C_I2CONCLR_SIC;
\r
625 /* Previously addressed with own SLA;
\r
626 * DATA byte has been received;
\r
627 * NOT ACK has been returned */
\r
628 case I2C_I2STAT_S_RX_PRE_SLA_DAT_NACK:
\r
629 /* DATA has been received, NOT ACK has been returned */
\r
630 case I2C_I2STAT_S_RX_PRE_GENCALL_DAT_NACK:
\r
631 I2Cx->CONCLR = I2C_I2CONCLR_SIC;
\r
635 * Note that: Return code only let us know a stop condition mixed
\r
636 * with a repeat start condition in the same code value.
\r
637 * So we should provide a time-out. In case this is really a stop
\r
638 * condition, this will return back after time out condition. Otherwise,
\r
639 * next session that is slave receive data will be completed.
\r
642 /* A Stop or a repeat start condition */
\r
643 case I2C_I2STAT_S_RX_STA_STO_SLVREC_SLVTRX:
\r
644 // Temporally lock the interrupt for timeout condition
\r
645 I2C_IntCmd(I2Cx, FALSE);
\r
646 I2Cx->CONCLR = I2C_I2CONCLR_SIC;
\r
648 timeout = I2C_SLAVE_TIME_OUT;
\r
650 if (I2Cx->CONSET & I2C_I2CONSET_SI){
\r
651 // re-Enable interrupt
\r
652 I2C_IntCmd(I2Cx, TRUE);
\r
657 // timeout occur, it's really a stop condition
\r
658 txrx_setup->status |= I2C_SETUP_STATUS_DONE;
\r
665 /* Writing phase -------------------------------------------------------- */
\r
666 /* Own SLA+R has been received, ACK has been returned */
\r
667 case I2C_I2STAT_S_TX_SLAR_ACK:
\r
668 /* Data has been transmitted, ACK has been received */
\r
669 case I2C_I2STAT_S_TX_DAT_ACK:
\r
671 * All data bytes that over-flow the specified receive
\r
672 * data length, just ignore them.
\r
674 if ((txrx_setup->tx_count < txrx_setup->tx_length) \
\r
675 && (txrx_setup->tx_data != NULL)){
\r
676 I2Cx->DAT = *(uint8_t *) (txrx_setup->tx_data + txrx_setup->tx_count);
\r
677 txrx_setup->tx_count++;
\r
679 I2Cx->CONSET = I2C_I2CONSET_AA;
\r
680 I2Cx->CONCLR = I2C_I2CONCLR_SIC;
\r
683 /* Data has been transmitted, NACK has been received,
\r
684 * that means there's no more data to send, exit now */
\r
686 * Note: Don't wait for stop event since in slave transmit mode,
\r
687 * since there no proof lets us know when a stop signal has been received
\r
690 case I2C_I2STAT_S_TX_DAT_NACK:
\r
691 I2Cx->CONSET = I2C_I2CONSET_AA;
\r
692 I2Cx->CONCLR = I2C_I2CONCLR_SIC;
\r
693 txrx_setup->status |= I2C_SETUP_STATUS_DONE;
\r
696 // Other status must be captured
\r
699 // Disable interrupt
\r
700 I2C_IntCmd(I2Cx, FALSE);
\r
701 I2Cx->CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC;
\r
702 I2C_SlaveComplete[tmp] = TRUE;
\r
708 /*********************************************************************//**
\r
709 * @brief Transmit and Receive data in master mode
\r
710 * @param[in] I2Cx I2C peripheral selected, should be:
\r
711 * - LPC_I2C0 :I2C0 peripheral
\r
712 * - LPC_I2C1 :I2C1 peripheral
\r
713 * @param[in] TransferCfg Pointer to a I2C_M_SETUP_Type structure that
\r
714 * contains specified information about the configuration
\r
715 * for master transfer.
\r
716 * @param[in] Opt a I2C_TRANSFER_OPT_Type type that selected for interrupt
\r
718 * @return Transmit/receive status, should be:
\r
723 * - In case of using I2C to transmit data only, either transmit length set to 0
\r
724 * or transmit data pointer set to NULL.
\r
725 * - In case of using I2C to receive data only, either receive length set to 0
\r
726 * or receive data pointer set to NULL.
\r
727 * - In case of using I2C to transmit followed by receive data, transmit length,
\r
728 * transmit data pointer, receive length and receive data pointer should be set
\r
730 **********************************************************************/
\r
731 Status I2C_MasterTransferData(LPC_I2Cn_Type *I2Cx, I2C_M_SETUP_Type *TransferCfg, \
\r
732 I2C_TRANSFER_OPT_Type Opt)
\r
736 uint32_t CodeStatus;
\r
739 // reset all default state
\r
740 txdat = (uint8_t *) TransferCfg->tx_data;
\r
741 rxdat = (uint8_t *) TransferCfg->rx_data;
\r
742 // Reset I2C setup value to default state
\r
743 TransferCfg->tx_count = 0;
\r
744 TransferCfg->rx_count = 0;
\r
745 TransferCfg->status = 0;
\r
747 if (Opt == I2C_TRANSFER_POLLING){
\r
749 /* First Start condition -------------------------------------------------------------- */
\r
750 TransferCfg->retransmissions_count = 0;
\r
752 // reset all default state
\r
753 txdat = (uint8_t *) TransferCfg->tx_data;
\r
754 rxdat = (uint8_t *) TransferCfg->rx_data;
\r
755 // Reset I2C setup value to default state
\r
756 TransferCfg->tx_count = 0;
\r
757 TransferCfg->rx_count = 0;
\r
761 CodeStatus = I2C_Start(I2Cx);
\r
762 if ((CodeStatus != I2C_I2STAT_M_TX_START) \
\r
763 && (CodeStatus != I2C_I2STAT_M_TX_RESTART)){
\r
764 TransferCfg->retransmissions_count++;
\r
765 if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){
\r
767 TransferCfg->status = CodeStatus;
\r
774 /* In case of sending data first --------------------------------------------------- */
\r
775 if ((TransferCfg->tx_length != 0) && (TransferCfg->tx_data != NULL)){
\r
777 /* Send slave address + WR direction bit = 0 ----------------------------------- */
\r
778 CodeStatus = I2C_SendByte(I2Cx, (TransferCfg->sl_addr7bit << 1));
\r
779 if (CodeStatus != I2C_I2STAT_M_TX_SLAW_ACK){
\r
780 TransferCfg->retransmissions_count++;
\r
781 if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){
\r
783 TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_NOACKF;
\r
790 /* Send a number of data bytes ---------------------------------------- */
\r
791 while (TransferCfg->tx_count < TransferCfg->tx_length)
\r
793 CodeStatus = I2C_SendByte(I2Cx, *txdat);
\r
794 if (CodeStatus != I2C_I2STAT_M_TX_DAT_ACK){
\r
795 TransferCfg->retransmissions_count++;
\r
796 if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){
\r
798 TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_NOACKF;
\r
806 TransferCfg->tx_count++;
\r
810 /* Second Start condition (Repeat Start) ------------------------------------------- */
\r
811 if ((TransferCfg->tx_length != 0) && (TransferCfg->tx_data != NULL) \
\r
812 && (TransferCfg->rx_length != 0) && (TransferCfg->rx_data != NULL)){
\r
814 CodeStatus = I2C_Start(I2Cx);
\r
815 if ((CodeStatus != I2C_I2STAT_M_RX_START) \
\r
816 && (CodeStatus != I2C_I2STAT_M_RX_RESTART)){
\r
817 TransferCfg->retransmissions_count++;
\r
818 if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){
\r
820 TransferCfg->status = CodeStatus;
\r
828 /* Then, start reading after sending data -------------------------------------- */
\r
829 if ((TransferCfg->rx_length != 0) && (TransferCfg->rx_data != NULL)){
\r
830 /* Send slave address + RD direction bit = 1 ----------------------------------- */
\r
832 CodeStatus = I2C_SendByte(I2Cx, ((TransferCfg->sl_addr7bit << 1) | 0x01));
\r
833 if (CodeStatus != I2C_I2STAT_M_RX_SLAR_ACK){
\r
834 TransferCfg->retransmissions_count++;
\r
835 if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){
\r
837 TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_NOACKF;
\r
844 /* Receive a number of data bytes ------------------------------------------------- */
\r
845 while (TransferCfg->rx_count < TransferCfg->rx_length){
\r
848 * Note that: if data length is only one, the master should not
\r
849 * issue an ACK signal on bus after reading to avoid of next data frame
\r
852 if (TransferCfg->rx_count < (TransferCfg->rx_length - 1)){
\r
853 // Issue an ACK signal for next data frame
\r
854 CodeStatus = I2C_GetByte(I2Cx, &tmp, TRUE);
\r
855 if (CodeStatus != I2C_I2STAT_M_RX_DAT_ACK){
\r
856 TransferCfg->retransmissions_count++;
\r
857 if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){
\r
859 TransferCfg->status = CodeStatus;
\r
866 // Do not issue an ACK signal
\r
867 CodeStatus = I2C_GetByte(I2Cx, &tmp, FALSE);
\r
868 if (CodeStatus != I2C_I2STAT_M_RX_DAT_NACK){
\r
869 TransferCfg->retransmissions_count++;
\r
870 if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){
\r
872 TransferCfg->status = CodeStatus;
\r
880 TransferCfg->rx_count++;
\r
884 /* Send STOP condition ------------------------------------------------- */
\r
889 // Send stop condition
\r
894 else if (Opt == I2C_TRANSFER_INTERRUPT){
\r
895 // Setup tx_rx data, callback and interrupt handler
\r
896 tmp = I2C_getNum(I2Cx);
\r
897 i2cdat[tmp].txrx_setup = (uint32_t) TransferCfg;
\r
898 // Set direction phase, write first
\r
899 i2cdat[tmp].dir = 0;
\r
901 /* First Start condition -------------------------------------------------------------- */
\r
902 I2Cx->CONCLR = I2C_I2CONCLR_SIC;
\r
903 I2Cx->CONSET = I2C_I2CONSET_STA;
\r
904 I2C_IntCmd(I2Cx, TRUE);
\r
913 /*********************************************************************//**
\r
914 * @brief Receive and Transmit data in slave mode
\r
915 * @param[in] I2Cx I2C peripheral selected, should be
\r
916 * - LPC_I2C0 :I2C0 peripheral
\r
917 * - LPC_I2C1 :I2C1 peripheral
\r
918 * @param[in] TransferCfg Pointer to a I2C_S_SETUP_Type structure that
\r
919 * contains specified information about the configuration for
\r
921 * @param[in] Opt I2C_TRANSFER_OPT_Type type that selected for interrupt
\r
923 * @return Transmit/receive status, could be:
\r
928 * The mode of slave's operation depends on the command sent from master on
\r
929 * the I2C bus. If the master send a SLA+W command, this sub-routine will
\r
930 * use receive data length and receive data pointer. If the master send a SLA+R
\r
931 * command, this sub-routine will use transmit data length and transmit data
\r
933 * If the master issue an repeat start command or a stop command, the slave will
\r
934 * enable an time out condition, during time out condition, if there's no activity
\r
935 * on I2C bus, the slave will exit, otherwise (i.e. the master send a SLA+R/W),
\r
936 * the slave then switch to relevant operation mode. The time out should be used
\r
937 * because the return status code can not show difference from stop and repeat
\r
938 * start command in slave operation.
\r
939 * In case of the expected data length from master is greater than data length
\r
940 * that slave can support:
\r
941 * - In case of reading operation (from master): slave will return I2C_I2DAT_IDLE_CHAR
\r
943 * - In case of writing operation (from master): slave will ignore remain data from master.
\r
944 **********************************************************************/
\r
945 Status I2C_SlaveTransferData(LPC_I2Cn_Type *I2Cx, I2C_S_SETUP_Type *TransferCfg, \
\r
946 I2C_TRANSFER_OPT_Type Opt)
\r
950 uint32_t CodeStatus = 0;
\r
955 // reset all default state
\r
956 txdat = (uint8_t *) TransferCfg->tx_data;
\r
957 rxdat = (uint8_t *) TransferCfg->rx_data;
\r
958 // Reset I2C setup value to default state
\r
959 TransferCfg->tx_count = 0;
\r
960 TransferCfg->rx_count = 0;
\r
961 TransferCfg->status = 0;
\r
965 if (Opt == I2C_TRANSFER_POLLING){
\r
967 /* Set AA bit to ACK command on I2C bus */
\r
968 I2Cx->CONSET = I2C_I2CONSET_AA;
\r
969 /* Clear SI bit to be ready ... */
\r
970 I2Cx->CONCLR = (I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC);
\r
977 /* Check SI flag ready */
\r
978 if (I2Cx->CONSET & I2C_I2CONSET_SI)
\r
982 switch (CodeStatus = (I2Cx->STAT & I2C_STAT_CODE_BITMASK))
\r
985 /* No status information */
\r
986 case I2C_I2STAT_NO_INF:
\r
987 I2Cx->CONSET = I2C_I2CONSET_AA;
\r
988 I2Cx->CONCLR = I2C_I2CONCLR_SIC;
\r
991 /* Reading phase -------------------------------------------------------- */
\r
992 /* Own SLA+R has been received, ACK has been returned */
\r
993 case I2C_I2STAT_S_RX_SLAW_ACK:
\r
994 /* General call address has been received, ACK has been returned */
\r
995 case I2C_I2STAT_S_RX_GENCALL_ACK:
\r
996 I2Cx->CONSET = I2C_I2CONSET_AA;
\r
997 I2Cx->CONCLR = I2C_I2CONCLR_SIC;
\r
1000 /* Previously addressed with own SLA;
\r
1001 * DATA byte has been received;
\r
1002 * ACK has been returned */
\r
1003 case I2C_I2STAT_S_RX_PRE_SLA_DAT_ACK:
\r
1004 /* DATA has been received, ACK hasn been return */
\r
1005 case I2C_I2STAT_S_RX_PRE_GENCALL_DAT_ACK:
\r
1007 * All data bytes that over-flow the specified receive
\r
1008 * data length, just ignore them.
\r
1010 if ((TransferCfg->rx_count < TransferCfg->rx_length) \
\r
1011 && (TransferCfg->rx_data != NULL)){
\r
1012 *rxdat++ = (uint8_t)I2Cx->DAT;
\r
1013 TransferCfg->rx_count++;
\r
1015 I2Cx->CONSET = I2C_I2CONSET_AA;
\r
1016 I2Cx->CONCLR = I2C_I2CONCLR_SIC;
\r
1019 /* Previously addressed with own SLA;
\r
1020 * DATA byte has been received;
\r
1021 * NOT ACK has been returned */
\r
1022 case I2C_I2STAT_S_RX_PRE_SLA_DAT_NACK:
\r
1023 /* DATA has been received, NOT ACK has been returned */
\r
1024 case I2C_I2STAT_S_RX_PRE_GENCALL_DAT_NACK:
\r
1025 I2Cx->CONCLR = I2C_I2CONCLR_SIC;
\r
1029 * Note that: Return code only let us know a stop condition mixed
\r
1030 * with a repeat start condition in the same code value.
\r
1031 * So we should provide a time-out. In case this is really a stop
\r
1032 * condition, this will return back after time out condition. Otherwise,
\r
1033 * next session that is slave receive data will be completed.
\r
1036 /* A Stop or a repeat start condition */
\r
1037 case I2C_I2STAT_S_RX_STA_STO_SLVREC_SLVTRX:
\r
1038 I2Cx->CONCLR = I2C_I2CONCLR_SIC;
\r
1039 // enable time out
\r
1044 /* Writing phase -------------------------------------------------------- */
\r
1045 /* Own SLA+R has been received, ACK has been returned */
\r
1046 case I2C_I2STAT_S_TX_SLAR_ACK:
\r
1047 /* Data has been transmitted, ACK has been received */
\r
1048 case I2C_I2STAT_S_TX_DAT_ACK:
\r
1050 * All data bytes that over-flow the specified receive
\r
1051 * data length, just ignore them.
\r
1053 if ((TransferCfg->tx_count < TransferCfg->tx_length) \
\r
1054 && (TransferCfg->tx_data != NULL)){
\r
1055 I2Cx->DAT = *txdat++;
\r
1056 TransferCfg->tx_count++;
\r
1058 I2Cx->CONSET = I2C_I2CONSET_AA;
\r
1059 I2Cx->CONCLR = I2C_I2CONCLR_SIC;
\r
1062 /* Data has been transmitted, NACK has been received,
\r
1063 * that means there's no more data to send, exit now */
\r
1065 * Note: Don't wait for stop event since in slave transmit mode,
\r
1066 * since there no proof lets us know when a stop signal has been received
\r
1069 case I2C_I2STAT_S_TX_DAT_NACK:
\r
1070 I2Cx->CONSET = I2C_I2CONSET_AA;
\r
1071 I2Cx->CONCLR = I2C_I2CONCLR_SIC;
\r
1072 // enable time out
\r
1077 // Other status must be captured
\r
1079 I2Cx->CONCLR = I2C_I2CONCLR_SIC;
\r
1082 } else if (time_en){
\r
1083 if (timeout++ > I2C_SLAVE_TIME_OUT){
\r
1084 // it's really a stop condition, goto end stage
\r
1091 /* Clear AA bit to disable ACK on I2C bus */
\r
1092 I2Cx->CONCLR = I2C_I2CONCLR_AAC;
\r
1093 // Check if there's no error during operation
\r
1095 TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_DONE;
\r
1099 /* Clear AA bit to disable ACK on I2C bus */
\r
1100 I2Cx->CONCLR = I2C_I2CONCLR_AAC;
\r
1102 TransferCfg->status = CodeStatus;
\r
1106 else if (Opt == I2C_TRANSFER_INTERRUPT){
\r
1107 // Setup tx_rx data, callback and interrupt handler
\r
1108 tmp = I2C_getNum(I2Cx);
\r
1109 i2cdat[tmp].txrx_setup = (uint32_t) TransferCfg;
\r
1110 // Set direction phase, read first
\r
1111 i2cdat[tmp].dir = 1;
\r
1114 I2Cx->CONSET = I2C_I2CONSET_AA;
\r
1115 I2Cx->CONCLR = I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC;
\r
1116 I2C_IntCmd(I2Cx, TRUE);
\r
1124 /*********************************************************************//**
\r
1125 * @brief Set Own slave address in I2C peripheral corresponding to
\r
1126 * parameter specified in OwnSlaveAddrConfigStruct.
\r
1127 * @param[in] I2Cx I2C peripheral selected, should be
\r
1128 * - LPC_I2C0 :I2C0 peripheral
\r
1129 * - LPC_I2C1 :I2C1 peripheral
\r
1130 * @param[in] OwnSlaveAddrConfigStruct Pointer to a I2C_OWNSLAVEADDR_CFG_Type
\r
1131 * structure that contains the configuration information for the
\r
1132 * specified I2C slave address.
\r
1134 **********************************************************************/
\r
1135 void I2C_SetOwnSlaveAddr(LPC_I2Cn_Type *I2Cx, I2C_OWNSLAVEADDR_CFG_Type *OwnSlaveAddrConfigStruct)
\r
1138 CHECK_PARAM(PARAM_I2Cx(I2Cx));
\r
1139 CHECK_PARAM(PARAM_I2C_SLAVEADDR_CH(OwnSlaveAddrConfigStruct->SlaveAddrChannel));
\r
1140 CHECK_PARAM(PARAM_FUNCTIONALSTATE(OwnSlaveAddrConfigStruct->GeneralCallState));
\r
1142 tmp = (((uint32_t)(OwnSlaveAddrConfigStruct->SlaveAddr_7bit << 1)) \
\r
1143 | ((OwnSlaveAddrConfigStruct->GeneralCallState == ENABLE) ? 0x01 : 0x00))& I2C_I2ADR_BITMASK;
\r
1144 switch (OwnSlaveAddrConfigStruct->SlaveAddrChannel)
\r
1148 I2Cx->MASK[0] = I2C_I2MASK_MASK((uint32_t) \
\r
1149 (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue));
\r
1153 I2Cx->MASK[1] = I2C_I2MASK_MASK((uint32_t) \
\r
1154 (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue));
\r
1158 I2Cx->MASK[2] = I2C_I2MASK_MASK((uint32_t) \
\r
1159 (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue));
\r
1163 I2Cx->MASK[3] = I2C_I2MASK_MASK((uint32_t) \
\r
1164 (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue));
\r
1170 /*********************************************************************//**
\r
1171 * @brief Configures functionality in I2C monitor mode
\r
1172 * @param[in] I2Cx I2C peripheral selected, should be
\r
1173 * - LPC_I2C0 :I2C0 peripheral
\r
1174 * - LPC_I2C1 :I2C1 peripheral
\r
1175 * @param[in] MonitorCfgType Monitor Configuration type, should be:
\r
1176 * - I2C_MONITOR_CFG_SCL_OUTPUT :I2C module can 'stretch'
\r
1177 * the clock line (hold it low) until it has had time to respond
\r
1178 * to an I2C interrupt.
\r
1179 * - I2C_MONITOR_CFG_MATCHALL :When this bit is set to '1'
\r
1180 * and the I2C is in monitor mode, an interrupt will be generated
\r
1181 * on ANY address received.
\r
1182 * @param[in] NewState New State of this function, should be:
\r
1183 * - ENABLE :Enable this function.
\r
1184 * - DISABLE :Disable this function.
\r
1186 **********************************************************************/
\r
1187 void I2C_MonitorModeConfig(LPC_I2Cn_Type *I2Cx, uint32_t MonitorCfgType, FunctionalState NewState)
\r
1189 CHECK_PARAM(PARAM_I2Cx(I2Cx));
\r
1190 CHECK_PARAM(PARAM_I2C_MONITOR_CFG(MonitorCfgType));
\r
1191 CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
\r
1193 if (NewState == ENABLE)
\r
1195 I2Cx->MMCTRL |= MonitorCfgType;
\r
1199 I2Cx->MMCTRL &= (~MonitorCfgType) & I2C_I2MMCTRL_BITMASK;
\r
1204 /*********************************************************************//**
\r
1205 * @brief Enable/Disable I2C monitor mode
\r
1206 * @param[in] I2Cx I2C peripheral selected, should be
\r
1207 * - LPC_I2C0 :I2C0 peripheral
\r
1208 * - LPC_I2C1 :I2C1 peripheral
\r
1209 * @param[in] NewState New State of this function, should be:
\r
1210 * - ENABLE :Enable monitor mode.
\r
1211 * - DISABLE :Disable monitor mode.
\r
1213 **********************************************************************/
\r
1214 void I2C_MonitorModeCmd(LPC_I2Cn_Type *I2Cx, FunctionalState NewState)
\r
1216 CHECK_PARAM(PARAM_I2Cx(I2Cx));
\r
1217 CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
\r
1219 if (NewState == ENABLE)
\r
1221 I2Cx->MMCTRL |= I2C_I2MMCTRL_MM_ENA;
\r
1222 I2Cx->CONSET = I2C_I2CONSET_AA;
\r
1223 I2Cx->CONCLR = I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC;
\r
1227 I2Cx->MMCTRL &= (~I2C_I2MMCTRL_MM_ENA) & I2C_I2MMCTRL_BITMASK;
\r
1228 I2Cx->CONCLR = I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC | I2C_I2CONCLR_AAC;
\r
1230 I2C_MonitorBufferIndex = 0;
\r
1234 /*********************************************************************//**
\r
1235 * @brief Get data from I2C data buffer in monitor mode.
\r
1236 * @param[in] I2Cx I2C peripheral selected, should be
\r
1237 * - LPC_I2C0 :I2C0 peripheral
\r
1238 * - LPC_I2C1 :I2C1 peripheral
\r
1240 * Note: In monitor mode, the I2C module may lose the ability to stretch
\r
1241 * the clock (stall the bus) if the ENA_SCL bit is not set. This means that
\r
1242 * the processor will have a limited amount of time to read the contents of
\r
1243 * the data received on the bus. If the processor reads the I2DAT shift
\r
1244 * register, as it ordinarily would, it could have only one bit-time to
\r
1245 * respond to the interrupt before the received data is overwritten by
\r
1247 **********************************************************************/
\r
1248 uint8_t I2C_MonitorGetDatabuffer(LPC_I2Cn_Type *I2Cx)
\r
1250 CHECK_PARAM(PARAM_I2Cx(I2Cx));
\r
1251 return ((uint8_t)(I2Cx->DATA_BUFFER));
\r
1255 /*********************************************************************//**
\r
1256 * @brief Get data from I2C data buffer in monitor mode.
\r
1257 * @param[in] I2Cx I2C peripheral selected, should be
\r
1258 * - LPC_I2C0 :I2C0 peripheral
\r
1259 * - LPC_I2C1 :I2C1 peripheral
\r
1261 * Note: In monitor mode, the I2C module may lose the ability to stretch
\r
1262 * the clock (stall the bus) if the ENA_SCL bit is not set. This means that
\r
1263 * the processor will have a limited amount of time to read the contents of
\r
1264 * the data received on the bus. If the processor reads the I2DAT shift
\r
1265 * register, as it ordinarily would, it could have only one bit-time to
\r
1266 * respond to the interrupt before the received data is overwritten by
\r
1268 **********************************************************************/
\r
1269 BOOL_8 I2C_MonitorHandler(LPC_I2Cn_Type *I2Cx, uint8_t *buffer, uint32_t size)
\r
1273 I2Cx->CONCLR = I2C_I2CONCLR_SIC;
\r
1275 buffer[I2C_MonitorBufferIndex] = (uint8_t)(I2Cx->DATA_BUFFER);
\r
1276 I2C_MonitorBufferIndex++;
\r
1277 if(I2C_MonitorBufferIndex >= size)
\r
1285 /*********************************************************************//**
\r
1286 * @brief Get status of Master Transfer
\r
1287 * @param[in] I2Cx I2C peripheral selected, should be:
\r
1288 * - LPC_I2C0 :I2C0 peripheral
\r
1289 * - LPC_I2C1 :I2C1 peripheral
\r
1290 * @return Master transfer status, could be:
\r
1291 * - TRUE :master transfer completed
\r
1292 * - FALSE :master transfer have not completed yet
\r
1293 **********************************************************************/
\r
1294 uint32_t I2C_MasterTransferComplete(LPC_I2Cn_Type *I2Cx)
\r
1296 uint32_t retval, tmp;
\r
1297 tmp = I2C_getNum(I2Cx);
\r
1298 retval = I2C_MasterComplete[tmp];
\r
1299 I2C_MasterComplete[tmp] = FALSE;
\r
1304 /*********************************************************************//**
\r
1305 * @brief Get status of Slave Transfer
\r
1306 * @param[in] I2Cx I2C peripheral selected, should be:
\r
1307 * - LPC_I2C0 :I2C0 peripheral
\r
1308 * - LPC_I2C1 :I2C1 peripheral
\r
1309 * @return Complete status, could be: TRUE/FALSE
\r
1310 **********************************************************************/
\r
1311 uint32_t I2C_SlaveTransferComplete(LPC_I2Cn_Type *I2Cx)
\r
1313 uint32_t retval, tmp;
\r
1314 tmp = I2C_getNum(I2Cx);
\r
1315 retval = I2C_SlaveComplete[tmp];
\r
1316 I2C_SlaveComplete[tmp] = FALSE;
\r
1332 /* --------------------------------- End Of File ------------------------------ */
\r