Monitor mode exploration

Dependencies:   mbed-rtos mbed

Committer:
jvanhook
Date:
Tue Jun 17 17:19:38 2014 +0000
Revision:
4:913c3147f211
Parent:
3:d84f98b6920e
first

Who changed what in which revision?

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