Date: March 20, 2011 This library is created from "LPC17xx CMSIS-Compliant Standard Peripheral Firmware Driver Library (GNU, Keil, IAR) (Jan 28, 2011)", available from NXP's website, under "All microcontrollers support documents" [[http://ics.nxp.com/support/documents/microcontrollers/?type=software]] You will need to follow [[/projects/libraries/svn/mbed/trunk/LPC1768/LPC17xx.h]] while using this library Examples provided here [[/users/frank26080115/programs/LPC1700CMSIS_Examples/]] The beautiful thing is that NXP does not place copyright protection on any of the files in here Only a few modifications are made to make it compile with the mbed online compiler, I fixed some warnings as well. This is untested as of March 20, 2011 Forum post about this library: [[/forum/mbed/topic/2030/]]

Committer:
frank26080115
Date:
Sun Mar 20 18:45:15 2011 +0000
Revision:
0:84d7747641aa

        

Who changed what in which revision?

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