Fork of Smoothie to port to mbed non-LPC targets.

Dependencies:   mbed

Fork of Smoothie by Stéphane Cachat

Committer:
Michael J. Spencer
Date:
Fri Feb 28 18:52:52 2014 -0800
Revision:
2:1df0b61d3b5a
Update to latest Smoothie.

Who changed what in which revision?

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