Monitor mode exploration
main.cpp@4:913c3147f211, 2014-06-17 (annotated)
- Committer:
- jvanhook
- Date:
- Tue Jun 17 17:19:38 2014 +0000
- Revision:
- 4:913c3147f211
- Parent:
- 3:d84f98b6920e
first
Who changed what in which revision?
| User | Revision | Line number | New 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 |