mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
AnnaBridge
Date:
Wed Feb 20 22:31:08 2019 +0000
Revision:
189:f392fc9709a3
Parent:
181:57724642e740
mbed library release version 165

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AnnaBridge 181:57724642e740 1 /* mbed Microcontroller Library
AnnaBridge 181:57724642e740 2 * Copyright (c) 2006-2013 ARM Limited
AnnaBridge 181:57724642e740 3 *
AnnaBridge 181:57724642e740 4 * Licensed under the Apache License, Version 2.0 (the "License");
AnnaBridge 181:57724642e740 5 * you may not use this file except in compliance with the License.
AnnaBridge 181:57724642e740 6 * You may obtain a copy of the License at
AnnaBridge 181:57724642e740 7 *
AnnaBridge 181:57724642e740 8 * http://www.apache.org/licenses/LICENSE-2.0
AnnaBridge 181:57724642e740 9 *
AnnaBridge 181:57724642e740 10 * Unless required by applicable law or agreed to in writing, software
AnnaBridge 181:57724642e740 11 * distributed under the License is distributed on an "AS IS" BASIS,
AnnaBridge 181:57724642e740 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
AnnaBridge 181:57724642e740 13 * See the License for the specific language governing permissions and
AnnaBridge 181:57724642e740 14 * limitations under the License.
AnnaBridge 181:57724642e740 15 */
AnnaBridge 181:57724642e740 16 #include "mbed_assert.h"
AnnaBridge 181:57724642e740 17 #include "dma_api.h"
AnnaBridge 181:57724642e740 18 #include "i2c_api.h"
AnnaBridge 181:57724642e740 19 #include "cmsis.h"
AnnaBridge 181:57724642e740 20 #include "PeripheralPins.h"
AnnaBridge 181:57724642e740 21 #include "r_typedefs.h"
AnnaBridge 181:57724642e740 22
AnnaBridge 181:57724642e740 23 #include "iodefine.h"
AnnaBridge 181:57724642e740 24 #include "RZ_A1_Init.h"
AnnaBridge 181:57724642e740 25
AnnaBridge 181:57724642e740 26 volatile struct st_riic *RIIC[] = RIIC_ADDRESS_LIST;
AnnaBridge 181:57724642e740 27
AnnaBridge 181:57724642e740 28 #define REG(N) \
AnnaBridge 181:57724642e740 29 RIIC[obj->i2c.i2c]->RIICn##N
AnnaBridge 181:57724642e740 30
AnnaBridge 181:57724642e740 31 /* RIICnCR1 */
AnnaBridge 181:57724642e740 32 #define CR1_RST (1 << 6)
AnnaBridge 181:57724642e740 33 #define CR1_ICE (1 << 7)
AnnaBridge 181:57724642e740 34
AnnaBridge 181:57724642e740 35 /* RIICnCR2 */
AnnaBridge 181:57724642e740 36 #define CR2_ST (1 << 1)
AnnaBridge 181:57724642e740 37 #define CR2_RS (1 << 2)
AnnaBridge 181:57724642e740 38 #define CR2_SP (1 << 3)
AnnaBridge 181:57724642e740 39 #define CR2_TRS (1 << 5)
AnnaBridge 181:57724642e740 40 #define CR2_BBSY (1 << 7)
AnnaBridge 181:57724642e740 41
AnnaBridge 181:57724642e740 42 /* RIICnMR3 */
AnnaBridge 181:57724642e740 43 #define MR3_ACKBT (1 << 3)
AnnaBridge 181:57724642e740 44 #define MR3_ACKWP (1 << 4)
AnnaBridge 181:57724642e740 45 #define MR3_WAIT (1 << 6)
AnnaBridge 181:57724642e740 46
AnnaBridge 181:57724642e740 47 /* RIICnSER */
AnnaBridge 181:57724642e740 48 #define SER_SAR0E (1 << 0)
AnnaBridge 181:57724642e740 49
AnnaBridge 181:57724642e740 50 /* RIICnSR1 */
AnnaBridge 181:57724642e740 51 #define SR1_AAS0 (1 << 0)
AnnaBridge 181:57724642e740 52
AnnaBridge 181:57724642e740 53 /* RIICnSR2 */
AnnaBridge 181:57724642e740 54 #define SR2_START (1 << 2)
AnnaBridge 181:57724642e740 55 #define SR2_STOP (1 << 3)
AnnaBridge 181:57724642e740 56 #define SR2_NACKF (1 << 4)
AnnaBridge 181:57724642e740 57 #define SR2_RDRF (1 << 5)
AnnaBridge 181:57724642e740 58 #define SR2_TEND (1 << 6)
AnnaBridge 181:57724642e740 59 #define SR2_TDRE (1 << 7)
AnnaBridge 181:57724642e740 60
AnnaBridge 181:57724642e740 61 #define WAIT_TIMEOUT (3600000) /* Loop counter : Time-out is about 1s. By 3600000 loops, measured value is 969ms. */
AnnaBridge 181:57724642e740 62
AnnaBridge 181:57724642e740 63 static inline int i2c_status(i2c_t *obj) {
AnnaBridge 181:57724642e740 64 return REG(SR2.UINT8[0]);
AnnaBridge 181:57724642e740 65 }
AnnaBridge 181:57724642e740 66
AnnaBridge 181:57724642e740 67 static void i2c_reg_reset(i2c_t *obj) {
AnnaBridge 181:57724642e740 68 /* full reset */
AnnaBridge 181:57724642e740 69 REG(CR1.UINT8[0]) &= ~CR1_ICE; // CR1.ICE off
AnnaBridge 181:57724642e740 70 REG(CR1.UINT8[0]) |= CR1_RST; // CR1.IICRST on
AnnaBridge 181:57724642e740 71 REG(CR1.UINT8[0]) |= CR1_ICE; // CR1.ICE on
AnnaBridge 181:57724642e740 72
AnnaBridge 181:57724642e740 73 REG(MR1.UINT8[0]) = 0x08; // P_phi /x 9bit (including Ack)
AnnaBridge 181:57724642e740 74 REG(SER.UINT8[0]) = 0x00; // no slave addr enabled
AnnaBridge 181:57724642e740 75
AnnaBridge 181:57724642e740 76 /* set frequency */
AnnaBridge 181:57724642e740 77 REG(MR1.UINT8[0]) |= obj->i2c.pclk_bit;
AnnaBridge 181:57724642e740 78 REG(BRL.UINT8[0]) = obj->i2c.width_low;
AnnaBridge 181:57724642e740 79 REG(BRH.UINT8[0]) = obj->i2c.width_hi;
AnnaBridge 181:57724642e740 80
AnnaBridge 181:57724642e740 81 REG(MR2.UINT8[0]) = 0x07;
AnnaBridge 181:57724642e740 82 REG(MR3.UINT8[0]) = 0x00;
AnnaBridge 181:57724642e740 83
AnnaBridge 181:57724642e740 84 REG(FER.UINT8[0]) = 0x72; // SCLE, NFE enabled, TMOT
AnnaBridge 181:57724642e740 85 REG(IER.UINT8[0]) = 0x00; // no interrupt
AnnaBridge 181:57724642e740 86
AnnaBridge 181:57724642e740 87 REG(CR1.UINT32) &= ~CR1_RST; // CR1.IICRST negate reset
AnnaBridge 181:57724642e740 88 }
AnnaBridge 181:57724642e740 89
AnnaBridge 181:57724642e740 90 static inline int i2c_wait_RDRF(i2c_t *obj) {
AnnaBridge 181:57724642e740 91 int timeout = 0;
AnnaBridge 181:57724642e740 92
AnnaBridge 181:57724642e740 93 /* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
AnnaBridge 181:57724642e740 94 while ((i2c_status(obj) & SR2_RDRF) == 0) {
AnnaBridge 181:57724642e740 95 timeout ++;
AnnaBridge 181:57724642e740 96 if (timeout >= WAIT_TIMEOUT) {
AnnaBridge 181:57724642e740 97 return -1;
AnnaBridge 181:57724642e740 98 }
AnnaBridge 181:57724642e740 99 }
AnnaBridge 181:57724642e740 100
AnnaBridge 181:57724642e740 101 return 0;
AnnaBridge 181:57724642e740 102 }
AnnaBridge 181:57724642e740 103
AnnaBridge 181:57724642e740 104 static int i2c_wait_TDRE(i2c_t *obj) {
AnnaBridge 181:57724642e740 105 int timeout = 0;
AnnaBridge 181:57724642e740 106
AnnaBridge 181:57724642e740 107 /* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
AnnaBridge 181:57724642e740 108 while ((i2c_status(obj) & SR2_TDRE) == 0) {
AnnaBridge 181:57724642e740 109 timeout ++;
AnnaBridge 181:57724642e740 110 if (timeout >= WAIT_TIMEOUT) {
AnnaBridge 181:57724642e740 111 return -1;
AnnaBridge 181:57724642e740 112 }
AnnaBridge 181:57724642e740 113 }
AnnaBridge 181:57724642e740 114
AnnaBridge 181:57724642e740 115 return 0;
AnnaBridge 181:57724642e740 116 }
AnnaBridge 181:57724642e740 117
AnnaBridge 181:57724642e740 118 static int i2c_wait_TEND(i2c_t *obj) {
AnnaBridge 181:57724642e740 119 int timeout = 0;
AnnaBridge 181:57724642e740 120
AnnaBridge 181:57724642e740 121 /* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
AnnaBridge 181:57724642e740 122 while ((i2c_status(obj) & SR2_TEND) == 0) {
AnnaBridge 181:57724642e740 123 timeout ++;
AnnaBridge 181:57724642e740 124 if (timeout >= WAIT_TIMEOUT) {
AnnaBridge 181:57724642e740 125 return -1;
AnnaBridge 181:57724642e740 126 }
AnnaBridge 181:57724642e740 127 }
AnnaBridge 181:57724642e740 128
AnnaBridge 181:57724642e740 129 return 0;
AnnaBridge 181:57724642e740 130 }
AnnaBridge 181:57724642e740 131
AnnaBridge 181:57724642e740 132
AnnaBridge 181:57724642e740 133 static int i2c_wait_START(i2c_t *obj) {
AnnaBridge 181:57724642e740 134 int timeout = 0;
AnnaBridge 181:57724642e740 135
AnnaBridge 181:57724642e740 136 /* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
AnnaBridge 181:57724642e740 137 while ((i2c_status(obj) & SR2_START) == 0) {
AnnaBridge 181:57724642e740 138 timeout ++;
AnnaBridge 181:57724642e740 139 if (timeout >= WAIT_TIMEOUT) {
AnnaBridge 181:57724642e740 140 return -1;
AnnaBridge 181:57724642e740 141 }
AnnaBridge 181:57724642e740 142 }
AnnaBridge 181:57724642e740 143
AnnaBridge 181:57724642e740 144 return 0;
AnnaBridge 181:57724642e740 145 }
AnnaBridge 181:57724642e740 146
AnnaBridge 181:57724642e740 147 static int i2c_wait_STOP(i2c_t *obj) {
AnnaBridge 181:57724642e740 148 int timeout = 0;
AnnaBridge 181:57724642e740 149
AnnaBridge 181:57724642e740 150 /* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
AnnaBridge 181:57724642e740 151 while ((i2c_status(obj) & SR2_STOP) == 0) {
AnnaBridge 181:57724642e740 152 timeout ++;
AnnaBridge 181:57724642e740 153 if (timeout >= WAIT_TIMEOUT) {
AnnaBridge 181:57724642e740 154 return -1;
AnnaBridge 181:57724642e740 155 }
AnnaBridge 181:57724642e740 156 }
AnnaBridge 181:57724642e740 157
AnnaBridge 181:57724642e740 158 return 0;
AnnaBridge 181:57724642e740 159 }
AnnaBridge 181:57724642e740 160
AnnaBridge 181:57724642e740 161 static int i2c_set_STOP(i2c_t *obj) {
AnnaBridge 181:57724642e740 162 /* SR2.STOP = 0 */
AnnaBridge 181:57724642e740 163 REG(SR2.UINT32) &= ~SR2_STOP;
AnnaBridge 181:57724642e740 164 /* Stop condition */
AnnaBridge 181:57724642e740 165 REG(CR2.UINT32) |= CR2_SP;
AnnaBridge 181:57724642e740 166
AnnaBridge 181:57724642e740 167 return 0;
AnnaBridge 181:57724642e740 168 }
AnnaBridge 181:57724642e740 169
AnnaBridge 181:57724642e740 170 static void i2c_set_SR2_NACKF_STOP(i2c_t *obj) {
AnnaBridge 181:57724642e740 171 /* SR2.NACKF = 0 */
AnnaBridge 181:57724642e740 172 REG(SR2.UINT32) &= ~SR2_NACKF;
AnnaBridge 181:57724642e740 173 /* SR2.STOP = 0 */
AnnaBridge 181:57724642e740 174 REG(SR2.UINT32) &= ~SR2_STOP;
AnnaBridge 181:57724642e740 175 }
AnnaBridge 181:57724642e740 176
AnnaBridge 181:57724642e740 177 static void i2c_set_MR3_NACK(i2c_t *obj) {
AnnaBridge 181:57724642e740 178 /* send a NOT ACK */
AnnaBridge 181:57724642e740 179 REG(MR3.UINT32) |= MR3_ACKWP;
AnnaBridge 181:57724642e740 180 REG(MR3.UINT32) |= MR3_ACKBT;
AnnaBridge 181:57724642e740 181 REG(MR3.UINT32) &= ~MR3_ACKWP;
AnnaBridge 181:57724642e740 182 }
AnnaBridge 181:57724642e740 183
AnnaBridge 181:57724642e740 184 static void i2c_set_MR3_ACK(i2c_t *obj) {
AnnaBridge 181:57724642e740 185 /* send a ACK */
AnnaBridge 181:57724642e740 186 REG(MR3.UINT32) |= MR3_ACKWP;
AnnaBridge 181:57724642e740 187 REG(MR3.UINT32) &= ~MR3_ACKBT;
AnnaBridge 181:57724642e740 188 REG(MR3.UINT32) &= ~MR3_ACKWP;
AnnaBridge 181:57724642e740 189 }
AnnaBridge 181:57724642e740 190
AnnaBridge 181:57724642e740 191 static inline void i2c_power_enable(i2c_t *obj) {
AnnaBridge 181:57724642e740 192 volatile uint8_t dummy;
AnnaBridge 181:57724642e740 193 switch ((int)obj->i2c.i2c) {
AnnaBridge 181:57724642e740 194 case I2C_0:
AnnaBridge 181:57724642e740 195 CPGSTBCR9 &= ~(0x80);
AnnaBridge 181:57724642e740 196 break;
AnnaBridge 181:57724642e740 197 case I2C_1:
AnnaBridge 181:57724642e740 198 CPGSTBCR9 &= ~(0x40);
AnnaBridge 181:57724642e740 199 break;
AnnaBridge 181:57724642e740 200 case I2C_2:
AnnaBridge 181:57724642e740 201 CPGSTBCR9 &= ~(0x20);
AnnaBridge 181:57724642e740 202 break;
AnnaBridge 181:57724642e740 203 case I2C_3:
AnnaBridge 181:57724642e740 204 CPGSTBCR9 &= ~(0x10);
AnnaBridge 181:57724642e740 205 break;
AnnaBridge 181:57724642e740 206 }
AnnaBridge 181:57724642e740 207 dummy = CPGSTBCR9;
AnnaBridge 181:57724642e740 208 (void)dummy;
AnnaBridge 181:57724642e740 209 }
AnnaBridge 181:57724642e740 210
AnnaBridge 181:57724642e740 211 void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
AnnaBridge 181:57724642e740 212 /* determine the I2C to use */
AnnaBridge 181:57724642e740 213 I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
AnnaBridge 181:57724642e740 214 I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
AnnaBridge 181:57724642e740 215 obj->i2c.i2c = pinmap_merge(i2c_sda, i2c_scl);
AnnaBridge 181:57724642e740 216 MBED_ASSERT((int)obj->i2c.i2c != NC);
AnnaBridge 181:57724642e740 217
AnnaBridge 181:57724642e740 218 /* enable power */
AnnaBridge 181:57724642e740 219 i2c_power_enable(obj);
AnnaBridge 181:57724642e740 220
AnnaBridge 181:57724642e740 221 /* set default frequency at 100k */
AnnaBridge 181:57724642e740 222 i2c_frequency(obj, 100000);
AnnaBridge 181:57724642e740 223
AnnaBridge 181:57724642e740 224 pinmap_pinout(sda, PinMap_I2C_SDA);
AnnaBridge 181:57724642e740 225 pinmap_pinout(scl, PinMap_I2C_SCL);
AnnaBridge 181:57724642e740 226
AnnaBridge 181:57724642e740 227 obj->i2c.last_stop_flag = 1;
AnnaBridge 181:57724642e740 228 }
AnnaBridge 181:57724642e740 229
AnnaBridge 181:57724642e740 230 inline int i2c_start(i2c_t *obj) {
AnnaBridge 181:57724642e740 231 int timeout = 0;
AnnaBridge 181:57724642e740 232
AnnaBridge 181:57724642e740 233 while ((REG(CR2.UINT32) & CR2_BBSY) != 0) {
AnnaBridge 181:57724642e740 234 timeout ++;
AnnaBridge 181:57724642e740 235 if (timeout >= obj->i2c.bbsy_wait_cnt) {
AnnaBridge 181:57724642e740 236 break;
AnnaBridge 181:57724642e740 237 }
AnnaBridge 181:57724642e740 238 }
AnnaBridge 181:57724642e740 239 /* Start Condition */
AnnaBridge 181:57724642e740 240 REG(CR2.UINT8[0]) |= CR2_ST;
AnnaBridge 181:57724642e740 241
AnnaBridge 181:57724642e740 242 return 0;
AnnaBridge 181:57724642e740 243 }
AnnaBridge 181:57724642e740 244
AnnaBridge 181:57724642e740 245 static inline int i2c_restart(i2c_t *obj) {
AnnaBridge 181:57724642e740 246 /* SR2.START = 0 */
AnnaBridge 181:57724642e740 247 REG(SR2.UINT32) &= ~SR2_START;
AnnaBridge 181:57724642e740 248 /* ReStart condition */
AnnaBridge 181:57724642e740 249 REG(CR2.UINT32) |= CR2_RS;
AnnaBridge 181:57724642e740 250
AnnaBridge 181:57724642e740 251 return 0;
AnnaBridge 181:57724642e740 252 }
AnnaBridge 181:57724642e740 253
AnnaBridge 181:57724642e740 254 inline int i2c_stop(i2c_t *obj) {
AnnaBridge 181:57724642e740 255 (void)i2c_set_STOP(obj);
AnnaBridge 181:57724642e740 256 (void)i2c_wait_STOP(obj);
AnnaBridge 181:57724642e740 257 i2c_set_SR2_NACKF_STOP(obj);
AnnaBridge 181:57724642e740 258
AnnaBridge 181:57724642e740 259 return 0;
AnnaBridge 181:57724642e740 260 }
AnnaBridge 181:57724642e740 261
AnnaBridge 181:57724642e740 262 static void i2c_set_err_noslave(i2c_t *obj) {
AnnaBridge 181:57724642e740 263 (void)i2c_set_STOP(obj);
AnnaBridge 181:57724642e740 264 (void)i2c_wait_STOP(obj);
AnnaBridge 181:57724642e740 265 i2c_set_SR2_NACKF_STOP(obj);
AnnaBridge 181:57724642e740 266 obj->i2c.last_stop_flag = 1;
AnnaBridge 181:57724642e740 267 }
AnnaBridge 181:57724642e740 268
AnnaBridge 181:57724642e740 269 static inline int i2c_do_write(i2c_t *obj, int value) {
AnnaBridge 181:57724642e740 270 int timeout = 0;
AnnaBridge 181:57724642e740 271
AnnaBridge 181:57724642e740 272 /* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
AnnaBridge 181:57724642e740 273 while ((i2c_status(obj) & SR2_TDRE) == 0) {
AnnaBridge 181:57724642e740 274 timeout ++;
AnnaBridge 181:57724642e740 275 if (timeout >= WAIT_TIMEOUT) {
AnnaBridge 181:57724642e740 276 return -1;
AnnaBridge 181:57724642e740 277 }
AnnaBridge 181:57724642e740 278 }
AnnaBridge 181:57724642e740 279 /* write the data */
AnnaBridge 181:57724642e740 280 REG(DRT.UINT32) = value;
AnnaBridge 181:57724642e740 281
AnnaBridge 181:57724642e740 282 return 0;
AnnaBridge 181:57724642e740 283 }
AnnaBridge 181:57724642e740 284
AnnaBridge 181:57724642e740 285 static inline int i2c_read_address_write(i2c_t *obj, int value) {
AnnaBridge 181:57724642e740 286 int status;
AnnaBridge 181:57724642e740 287
AnnaBridge 181:57724642e740 288 status = i2c_wait_TDRE(obj);
AnnaBridge 181:57724642e740 289 if (status == 0) {
AnnaBridge 181:57724642e740 290 /* write the data */
AnnaBridge 181:57724642e740 291 REG(DRT.UINT32) = value;
AnnaBridge 181:57724642e740 292 }
AnnaBridge 181:57724642e740 293
AnnaBridge 181:57724642e740 294 return status;
AnnaBridge 181:57724642e740 295
AnnaBridge 181:57724642e740 296 }
AnnaBridge 181:57724642e740 297
AnnaBridge 181:57724642e740 298 static inline int i2c_do_read(i2c_t *obj, int last) {
AnnaBridge 181:57724642e740 299 if (last == 2) {
AnnaBridge 181:57724642e740 300 /* this time is befor last byte read */
AnnaBridge 181:57724642e740 301 /* Set MR3 WAIT bit is 1 */;
AnnaBridge 181:57724642e740 302 REG(MR3.UINT32) |= MR3_WAIT;
AnnaBridge 181:57724642e740 303 } else if (last == 1) {
AnnaBridge 181:57724642e740 304 i2c_set_MR3_NACK(obj);
AnnaBridge 181:57724642e740 305 } else {
AnnaBridge 181:57724642e740 306 i2c_set_MR3_ACK(obj);
AnnaBridge 181:57724642e740 307 }
AnnaBridge 181:57724642e740 308
AnnaBridge 181:57724642e740 309 /* return the data */
AnnaBridge 181:57724642e740 310 return (REG(DRR.UINT32) & 0xFF);
AnnaBridge 181:57724642e740 311 }
AnnaBridge 181:57724642e740 312
AnnaBridge 181:57724642e740 313 void i2c_frequency(i2c_t *obj, int hz) {
AnnaBridge 181:57724642e740 314 float64_t pclk_val;
AnnaBridge 181:57724642e740 315 float64_t wait_utime;
AnnaBridge 181:57724642e740 316 volatile float64_t bps;
AnnaBridge 181:57724642e740 317 volatile float64_t L_time; /* H Width period */
AnnaBridge 181:57724642e740 318 volatile float64_t H_time; /* L Width period */
AnnaBridge 181:57724642e740 319 uint32_t tmp_L_width;
AnnaBridge 181:57724642e740 320 uint32_t tmp_H_width;
AnnaBridge 181:57724642e740 321 uint32_t remainder;
AnnaBridge 181:57724642e740 322 uint32_t wk_cks = 0;
AnnaBridge 181:57724642e740 323
AnnaBridge 181:57724642e740 324 /* set PCLK */
AnnaBridge 181:57724642e740 325 if (false == RZ_A1_IsClockMode0()) {
AnnaBridge 181:57724642e740 326 pclk_val = (float64_t)CM1_RENESAS_RZ_A1_P0_CLK;
AnnaBridge 181:57724642e740 327 } else {
AnnaBridge 181:57724642e740 328 pclk_val = (float64_t)CM0_RENESAS_RZ_A1_P0_CLK;
AnnaBridge 181:57724642e740 329 }
AnnaBridge 181:57724642e740 330
AnnaBridge 181:57724642e740 331 /* Min 10kHz, Max 400kHz */
AnnaBridge 181:57724642e740 332 if (hz < 10000) {
AnnaBridge 181:57724642e740 333 bps = 10000;
AnnaBridge 181:57724642e740 334 } else if (hz > 400000) {
AnnaBridge 181:57724642e740 335 bps = 400000;
AnnaBridge 181:57724642e740 336 } else {
AnnaBridge 181:57724642e740 337 bps = (float64_t)hz;
AnnaBridge 181:57724642e740 338 }
AnnaBridge 181:57724642e740 339
AnnaBridge 181:57724642e740 340 /* Calculation L width time */
AnnaBridge 181:57724642e740 341 L_time = (1 / (2 * bps)); /* Harf period of frequency */
AnnaBridge 181:57724642e740 342 H_time = L_time;
AnnaBridge 181:57724642e740 343
AnnaBridge 181:57724642e740 344 /* Check I2C mode of Speed */
AnnaBridge 181:57724642e740 345 if (bps > 100000) {
AnnaBridge 181:57724642e740 346 /* Fast-mode */
AnnaBridge 181:57724642e740 347 L_time -= 102E-9; /* Falling time of SCL clock. */
AnnaBridge 181:57724642e740 348 H_time -= 138E-9; /* Rising time of SCL clock. */
AnnaBridge 181:57724642e740 349 /* Check L wideth */
AnnaBridge 181:57724642e740 350 if (L_time < 1.3E-6) {
AnnaBridge 181:57724642e740 351 /* Wnen L width less than 1.3us */
AnnaBridge 181:57724642e740 352 /* Subtract Rise up and down time for SCL from H/L width */
AnnaBridge 181:57724642e740 353 L_time = 1.3E-6;
AnnaBridge 181:57724642e740 354 H_time = (1 / bps) - L_time - 138E-9 - 102E-9;
AnnaBridge 181:57724642e740 355 }
AnnaBridge 181:57724642e740 356 }
AnnaBridge 181:57724642e740 357
AnnaBridge 181:57724642e740 358 tmp_L_width = (uint32_t)(L_time * pclk_val * 10);
AnnaBridge 181:57724642e740 359 tmp_L_width >>= 1;
AnnaBridge 181:57724642e740 360 wk_cks++;
AnnaBridge 181:57724642e740 361 while (tmp_L_width >= 341) {
AnnaBridge 181:57724642e740 362 tmp_L_width >>= 1;
AnnaBridge 181:57724642e740 363 wk_cks++;
AnnaBridge 181:57724642e740 364 }
AnnaBridge 181:57724642e740 365 remainder = tmp_L_width % 10;
AnnaBridge 181:57724642e740 366 tmp_L_width = ((tmp_L_width + 9) / 10) - 3; /* carry */
AnnaBridge 181:57724642e740 367
AnnaBridge 181:57724642e740 368 tmp_H_width = (uint32_t)(H_time * pclk_val * 10);
AnnaBridge 181:57724642e740 369 tmp_H_width >>= wk_cks;
AnnaBridge 181:57724642e740 370 if (remainder == 0) {
AnnaBridge 181:57724642e740 371 tmp_H_width = ((tmp_H_width + 9) / 10) - 3; /* carry */
AnnaBridge 181:57724642e740 372 } else {
AnnaBridge 181:57724642e740 373 remainder += tmp_H_width % 10;
AnnaBridge 181:57724642e740 374 tmp_H_width = (tmp_H_width / 10) - 3;
AnnaBridge 181:57724642e740 375 if (remainder > 10) {
AnnaBridge 181:57724642e740 376 tmp_H_width += 1; /* fine adjustment */
AnnaBridge 181:57724642e740 377 }
AnnaBridge 181:57724642e740 378 }
AnnaBridge 181:57724642e740 379 /* timeout of BBSY bit is minimum low width by frequency */
AnnaBridge 181:57724642e740 380 /* so timeout calculates "(low width) * 2" by frequency */
AnnaBridge 181:57724642e740 381 wait_utime = (L_time * 2) * 1000000;
AnnaBridge 181:57724642e740 382 /* 1 wait of BBSY bit is about 0.3us. if it's below 0.3us, wait count is set as 1. */
AnnaBridge 181:57724642e740 383 if (wait_utime <= 0.3) {
AnnaBridge 181:57724642e740 384 obj->i2c.bbsy_wait_cnt = 1;
AnnaBridge 181:57724642e740 385 } else {
AnnaBridge 181:57724642e740 386 obj->i2c.bbsy_wait_cnt = (int)(wait_utime / 0.3);
AnnaBridge 181:57724642e740 387 }
AnnaBridge 181:57724642e740 388
AnnaBridge 181:57724642e740 389
AnnaBridge 181:57724642e740 390 /* I2C Rate */
AnnaBridge 181:57724642e740 391 obj->i2c.pclk_bit = (uint8_t)(0x10 * wk_cks); /* P_phi / xx */
AnnaBridge 181:57724642e740 392 obj->i2c.width_low = (uint8_t)(tmp_L_width | 0x000000E0);
AnnaBridge 181:57724642e740 393 obj->i2c.width_hi = (uint8_t)(tmp_H_width | 0x000000E0);
AnnaBridge 181:57724642e740 394
AnnaBridge 181:57724642e740 395 /* full reset */
AnnaBridge 181:57724642e740 396 i2c_reg_reset(obj);
AnnaBridge 181:57724642e740 397 }
AnnaBridge 181:57724642e740 398
AnnaBridge 181:57724642e740 399 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
AnnaBridge 181:57724642e740 400 int count = 0;
AnnaBridge 181:57724642e740 401 int status;
AnnaBridge 181:57724642e740 402 int value;
AnnaBridge 181:57724642e740 403
AnnaBridge 181:57724642e740 404 i2c_set_MR3_ACK(obj);
AnnaBridge 181:57724642e740 405 /* There is a STOP condition for last processing */
AnnaBridge 181:57724642e740 406 if (obj->i2c.last_stop_flag != 0) {
AnnaBridge 181:57724642e740 407 status = i2c_start(obj);
AnnaBridge 181:57724642e740 408 if (status != 0) {
AnnaBridge 181:57724642e740 409 i2c_set_err_noslave(obj);
AnnaBridge 181:57724642e740 410 return I2C_ERROR_BUS_BUSY;
AnnaBridge 181:57724642e740 411 }
AnnaBridge 181:57724642e740 412 }
AnnaBridge 181:57724642e740 413 obj->i2c.last_stop_flag = stop;
AnnaBridge 181:57724642e740 414 /* Send Slave address */
AnnaBridge 181:57724642e740 415 status = i2c_read_address_write(obj, (address | 0x01));
AnnaBridge 181:57724642e740 416 if (status != 0) {
AnnaBridge 181:57724642e740 417 i2c_set_err_noslave(obj);
AnnaBridge 181:57724642e740 418 return I2C_ERROR_NO_SLAVE;
AnnaBridge 181:57724642e740 419 }
AnnaBridge 181:57724642e740 420 /* wait RDRF */
AnnaBridge 181:57724642e740 421 status = i2c_wait_RDRF(obj);
AnnaBridge 181:57724642e740 422 /* check ACK/NACK */
AnnaBridge 181:57724642e740 423 if ((status != 0) || ((REG(SR2.UINT32) & SR2_NACKF) != 0)) {
AnnaBridge 181:57724642e740 424 /* Slave sends NACK */
AnnaBridge 181:57724642e740 425 (void)i2c_set_STOP(obj);
AnnaBridge 181:57724642e740 426 /* dummy read */
AnnaBridge 181:57724642e740 427 value = REG(DRR.UINT32);
AnnaBridge 181:57724642e740 428 (void)i2c_wait_STOP(obj);
AnnaBridge 181:57724642e740 429 i2c_set_SR2_NACKF_STOP(obj);
AnnaBridge 181:57724642e740 430 obj->i2c.last_stop_flag = 1;
AnnaBridge 181:57724642e740 431 return I2C_ERROR_NO_SLAVE;
AnnaBridge 181:57724642e740 432 }
AnnaBridge 181:57724642e740 433 if (length != 0) {
AnnaBridge 181:57724642e740 434 /* Read in all except last byte */
AnnaBridge 181:57724642e740 435 if (length > 2) {
AnnaBridge 181:57724642e740 436 /* dummy read */
AnnaBridge 181:57724642e740 437 value = REG(DRR.UINT32);
AnnaBridge 181:57724642e740 438 for (count = 0; count < (length - 1); count++) {
AnnaBridge 181:57724642e740 439 /* wait for it to arrive */
AnnaBridge 181:57724642e740 440 status = i2c_wait_RDRF(obj);
AnnaBridge 181:57724642e740 441 if (status != 0) {
AnnaBridge 181:57724642e740 442 i2c_set_err_noslave(obj);
AnnaBridge 181:57724642e740 443 return I2C_ERROR_NO_SLAVE;
AnnaBridge 181:57724642e740 444 }
AnnaBridge 181:57724642e740 445 /* Recieve the data */
AnnaBridge 181:57724642e740 446 if (count == (length - 2)) {
AnnaBridge 181:57724642e740 447 value = i2c_do_read(obj, 1);
AnnaBridge 181:57724642e740 448 } else if ((length >= 3) && (count == (length - 3))) {
AnnaBridge 181:57724642e740 449 value = i2c_do_read(obj, 2);
AnnaBridge 181:57724642e740 450 } else {
AnnaBridge 181:57724642e740 451 value = i2c_do_read(obj, 0);
AnnaBridge 181:57724642e740 452 }
AnnaBridge 181:57724642e740 453 data[count] = (char)value;
AnnaBridge 181:57724642e740 454 }
AnnaBridge 181:57724642e740 455 } else if (length == 2) {
AnnaBridge 181:57724642e740 456 /* Set MR3 WAIT bit is 1 */
AnnaBridge 181:57724642e740 457 REG(MR3.UINT32) |= MR3_WAIT;
AnnaBridge 181:57724642e740 458 /* dummy read */
AnnaBridge 181:57724642e740 459 value = REG(DRR.UINT32);
AnnaBridge 181:57724642e740 460 /* wait for it to arrive */
AnnaBridge 181:57724642e740 461 status = i2c_wait_RDRF(obj);
AnnaBridge 181:57724642e740 462 if (status != 0) {
AnnaBridge 181:57724642e740 463 i2c_set_err_noslave(obj);
AnnaBridge 181:57724642e740 464 return I2C_ERROR_NO_SLAVE;
AnnaBridge 181:57724642e740 465 }
AnnaBridge 181:57724642e740 466 i2c_set_MR3_NACK(obj);
AnnaBridge 181:57724642e740 467 data[count] = (char)REG(DRR.UINT32);
AnnaBridge 181:57724642e740 468 count++;
AnnaBridge 181:57724642e740 469 } else {
AnnaBridge 181:57724642e740 470 /* length == 1 */
AnnaBridge 181:57724642e740 471 /* Set MR3 WAIT bit is 1 */;
AnnaBridge 181:57724642e740 472 REG(MR3.UINT32) |= MR3_WAIT;
AnnaBridge 181:57724642e740 473 i2c_set_MR3_NACK(obj);
AnnaBridge 181:57724642e740 474 /* dummy read */
AnnaBridge 181:57724642e740 475 value = REG(DRR.UINT32);
AnnaBridge 181:57724642e740 476 }
AnnaBridge 181:57724642e740 477 /* wait for it to arrive */
AnnaBridge 181:57724642e740 478 status = i2c_wait_RDRF(obj);
AnnaBridge 181:57724642e740 479 if (status != 0) {
AnnaBridge 181:57724642e740 480 i2c_set_err_noslave(obj);
AnnaBridge 181:57724642e740 481 return I2C_ERROR_NO_SLAVE;
AnnaBridge 181:57724642e740 482 }
AnnaBridge 181:57724642e740 483
AnnaBridge 181:57724642e740 484 /* If not repeated start, send stop. */
AnnaBridge 181:57724642e740 485 if (stop) {
AnnaBridge 181:57724642e740 486 (void)i2c_set_STOP(obj);
AnnaBridge 181:57724642e740 487 /* RIICnDRR read */
AnnaBridge 181:57724642e740 488 value = (REG(DRR.UINT32) & 0xFF);
AnnaBridge 181:57724642e740 489 data[count] = (char)value;
AnnaBridge 181:57724642e740 490 /* RIICnMR3.WAIT = 0 */
AnnaBridge 181:57724642e740 491 REG(MR3.UINT32) &= ~MR3_WAIT;
AnnaBridge 181:57724642e740 492 (void)i2c_wait_STOP(obj);
AnnaBridge 181:57724642e740 493 i2c_set_SR2_NACKF_STOP(obj);
AnnaBridge 181:57724642e740 494 } else {
AnnaBridge 181:57724642e740 495 (void)i2c_restart(obj);
AnnaBridge 181:57724642e740 496 /* RIICnDRR read */
AnnaBridge 181:57724642e740 497 value = (REG(DRR.UINT32) & 0xFF);
AnnaBridge 181:57724642e740 498 data[count] = (char)value;
AnnaBridge 181:57724642e740 499 /* RIICnMR3.WAIT = 0 */
AnnaBridge 181:57724642e740 500 REG(MR3.UINT32) &= ~MR3_WAIT;
AnnaBridge 181:57724642e740 501 (void)i2c_wait_START(obj);
AnnaBridge 181:57724642e740 502 /* SR2.START = 0 */
AnnaBridge 181:57724642e740 503 REG(SR2.UINT32) &= ~SR2_START;
AnnaBridge 181:57724642e740 504 }
AnnaBridge 181:57724642e740 505 } else {
AnnaBridge 181:57724642e740 506 /* If not repeated start, send stop. */
AnnaBridge 181:57724642e740 507 if (stop) {
AnnaBridge 181:57724642e740 508 (void)i2c_set_STOP(obj);
AnnaBridge 181:57724642e740 509 (void)i2c_wait_STOP(obj);
AnnaBridge 181:57724642e740 510 i2c_set_SR2_NACKF_STOP(obj);
AnnaBridge 181:57724642e740 511 } else {
AnnaBridge 181:57724642e740 512 (void)i2c_restart(obj);
AnnaBridge 181:57724642e740 513 (void)i2c_wait_START(obj);
AnnaBridge 181:57724642e740 514 /* SR2.START = 0 */
AnnaBridge 181:57724642e740 515 REG(SR2.UINT32) &= ~SR2_START;
AnnaBridge 181:57724642e740 516 }
AnnaBridge 181:57724642e740 517 }
AnnaBridge 181:57724642e740 518
AnnaBridge 181:57724642e740 519 return length;
AnnaBridge 181:57724642e740 520 }
AnnaBridge 181:57724642e740 521
AnnaBridge 181:57724642e740 522 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
AnnaBridge 181:57724642e740 523 int cnt;
AnnaBridge 181:57724642e740 524 int status;
AnnaBridge 181:57724642e740 525
AnnaBridge 181:57724642e740 526 /* There is a STOP condition for last processing */
AnnaBridge 181:57724642e740 527 if (obj->i2c.last_stop_flag != 0) {
AnnaBridge 181:57724642e740 528 status = i2c_start(obj);
AnnaBridge 181:57724642e740 529 if (status != 0) {
AnnaBridge 181:57724642e740 530 i2c_set_err_noslave(obj);
AnnaBridge 181:57724642e740 531 return I2C_ERROR_BUS_BUSY;
AnnaBridge 181:57724642e740 532 }
AnnaBridge 181:57724642e740 533 }
AnnaBridge 181:57724642e740 534 obj->i2c.last_stop_flag = stop;
AnnaBridge 181:57724642e740 535 /* Send Slave address */
AnnaBridge 181:57724642e740 536 status = i2c_do_write(obj, address);
AnnaBridge 181:57724642e740 537 if (status != 0) {
AnnaBridge 181:57724642e740 538 i2c_set_err_noslave(obj);
AnnaBridge 181:57724642e740 539 return I2C_ERROR_NO_SLAVE;
AnnaBridge 181:57724642e740 540 }
AnnaBridge 181:57724642e740 541 /* Wait send end */
AnnaBridge 181:57724642e740 542 status = i2c_wait_TEND(obj);
AnnaBridge 181:57724642e740 543 if ((status != 0) || ((REG(SR2.UINT32) & SR2_NACKF) != 0)) {
AnnaBridge 181:57724642e740 544 /* Slave sends NACK */
AnnaBridge 181:57724642e740 545 i2c_set_err_noslave(obj);
AnnaBridge 181:57724642e740 546 return I2C_ERROR_NO_SLAVE;
AnnaBridge 181:57724642e740 547 }
AnnaBridge 181:57724642e740 548 /* Send Write data */
AnnaBridge 181:57724642e740 549 for (cnt=0; cnt<length; cnt++) {
AnnaBridge 181:57724642e740 550 status = i2c_do_write(obj, data[cnt]);
AnnaBridge 181:57724642e740 551 if(status != 0) {
AnnaBridge 181:57724642e740 552 i2c_set_err_noslave(obj);
AnnaBridge 181:57724642e740 553 return cnt;
AnnaBridge 181:57724642e740 554 } else {
AnnaBridge 181:57724642e740 555 /* Wait send end */
AnnaBridge 181:57724642e740 556 status = i2c_wait_TEND(obj);
AnnaBridge 181:57724642e740 557 if ((status != 0) || ((REG(SR2.UINT32) & SR2_NACKF) != 0)) {
AnnaBridge 181:57724642e740 558 /* Slave sends NACK */
AnnaBridge 181:57724642e740 559 i2c_set_err_noslave(obj);
AnnaBridge 181:57724642e740 560 return I2C_ERROR_NO_SLAVE;
AnnaBridge 181:57724642e740 561 }
AnnaBridge 181:57724642e740 562 }
AnnaBridge 181:57724642e740 563 }
AnnaBridge 181:57724642e740 564 /* If not repeated start, send stop. */
AnnaBridge 181:57724642e740 565 if (stop) {
AnnaBridge 181:57724642e740 566 (void)i2c_set_STOP(obj);
AnnaBridge 181:57724642e740 567 (void)i2c_wait_STOP(obj);
AnnaBridge 181:57724642e740 568 i2c_set_SR2_NACKF_STOP(obj);
AnnaBridge 181:57724642e740 569 } else {
AnnaBridge 181:57724642e740 570 (void)i2c_restart(obj);
AnnaBridge 181:57724642e740 571 (void)i2c_wait_START(obj);
AnnaBridge 181:57724642e740 572 /* SR2.START = 0 */
AnnaBridge 181:57724642e740 573 REG(SR2.UINT32) &= ~SR2_START;
AnnaBridge 181:57724642e740 574
AnnaBridge 181:57724642e740 575 }
AnnaBridge 181:57724642e740 576
AnnaBridge 181:57724642e740 577 return length;
AnnaBridge 181:57724642e740 578 }
AnnaBridge 181:57724642e740 579
AnnaBridge 181:57724642e740 580 void i2c_reset(i2c_t *obj) {
AnnaBridge 181:57724642e740 581 (void)i2c_set_STOP(obj);
AnnaBridge 181:57724642e740 582 (void)i2c_wait_STOP(obj);
AnnaBridge 181:57724642e740 583 i2c_set_SR2_NACKF_STOP(obj);
AnnaBridge 181:57724642e740 584 }
AnnaBridge 181:57724642e740 585
AnnaBridge 181:57724642e740 586 int i2c_byte_read(i2c_t *obj, int last) {
AnnaBridge 181:57724642e740 587 int status;
AnnaBridge 181:57724642e740 588 int data;
AnnaBridge 181:57724642e740 589
AnnaBridge 181:57724642e740 590 data = i2c_do_read(obj, last);
AnnaBridge 181:57724642e740 591 /* wait for it to arrive */
AnnaBridge 181:57724642e740 592 status = i2c_wait_RDRF(obj);
AnnaBridge 181:57724642e740 593 if (status != 0) {
AnnaBridge 181:57724642e740 594 i2c_set_SR2_NACKF_STOP(obj);
AnnaBridge 181:57724642e740 595 return I2C_ERROR_NO_SLAVE;
AnnaBridge 181:57724642e740 596 }
AnnaBridge 181:57724642e740 597
AnnaBridge 181:57724642e740 598 return data;
AnnaBridge 181:57724642e740 599 }
AnnaBridge 181:57724642e740 600
AnnaBridge 181:57724642e740 601 int i2c_byte_write(i2c_t *obj, int data) {
AnnaBridge 181:57724642e740 602 int ack = 0;
AnnaBridge 181:57724642e740 603 int status;
AnnaBridge 181:57724642e740 604 int timeout = 0;
AnnaBridge 181:57724642e740 605
AnnaBridge 181:57724642e740 606 status = i2c_do_write(obj, (data & 0xFF));
AnnaBridge 181:57724642e740 607 if (status != 0) {
AnnaBridge 181:57724642e740 608 i2c_set_SR2_NACKF_STOP(obj);
AnnaBridge 181:57724642e740 609 } else {
AnnaBridge 181:57724642e740 610 while (((i2c_status(obj) & SR2_RDRF) == 0) && ((i2c_status(obj) & SR2_TEND) == 0)) {
AnnaBridge 181:57724642e740 611 timeout++;
AnnaBridge 181:57724642e740 612 if (timeout >= WAIT_TIMEOUT) {
AnnaBridge 181:57724642e740 613 return ack;
AnnaBridge 181:57724642e740 614 }
AnnaBridge 181:57724642e740 615 }
AnnaBridge 181:57724642e740 616 /* check ACK/NACK */
AnnaBridge 181:57724642e740 617 if ((REG(SR2.UINT32) & SR2_NACKF) != 0) {
AnnaBridge 181:57724642e740 618 /* NACK */
AnnaBridge 181:57724642e740 619 i2c_set_SR2_NACKF_STOP(obj);
AnnaBridge 181:57724642e740 620 } else {
AnnaBridge 181:57724642e740 621 ack = 1;
AnnaBridge 181:57724642e740 622 }
AnnaBridge 181:57724642e740 623 }
AnnaBridge 181:57724642e740 624
AnnaBridge 181:57724642e740 625 return ack;
AnnaBridge 181:57724642e740 626 }
AnnaBridge 181:57724642e740 627
AnnaBridge 181:57724642e740 628 void i2c_slave_mode(i2c_t *obj, int enable_slave) {
AnnaBridge 181:57724642e740 629 if (enable_slave != 0) {
AnnaBridge 181:57724642e740 630 REG(SER.UINT32) |= SER_SAR0E; // only slave addr 0 is enabled
AnnaBridge 181:57724642e740 631 } else {
AnnaBridge 181:57724642e740 632 REG(SER.UINT32) &= ~SER_SAR0E; // no slave addr enabled
AnnaBridge 181:57724642e740 633 }
AnnaBridge 181:57724642e740 634 }
AnnaBridge 181:57724642e740 635
AnnaBridge 181:57724642e740 636 int i2c_slave_receive(i2c_t *obj) {
AnnaBridge 181:57724642e740 637 int status;
AnnaBridge 181:57724642e740 638 int retval;
AnnaBridge 181:57724642e740 639
AnnaBridge 181:57724642e740 640 status = (REG(SR1.UINT8[0]) & SR1_AAS0);
AnnaBridge 181:57724642e740 641 status |= (REG(CR2.UINT8[0]) & CR2_TRS) >> 4;
AnnaBridge 181:57724642e740 642
AnnaBridge 181:57724642e740 643 switch(status) {
AnnaBridge 181:57724642e740 644 case 0x01:
AnnaBridge 181:57724642e740 645 /* the master is writing to this slave */
AnnaBridge 181:57724642e740 646 retval = 3;
AnnaBridge 181:57724642e740 647 break;
AnnaBridge 181:57724642e740 648 case 0x02:
AnnaBridge 181:57724642e740 649 /* the master is writing to all slave */
AnnaBridge 181:57724642e740 650 retval = 2;
AnnaBridge 181:57724642e740 651 break;
AnnaBridge 181:57724642e740 652 case 0x03:
AnnaBridge 181:57724642e740 653 /* the master has requested a read from this slave */
AnnaBridge 181:57724642e740 654 retval = 1;
AnnaBridge 181:57724642e740 655 break;
AnnaBridge 181:57724642e740 656 default :
AnnaBridge 181:57724642e740 657 /* no data */
AnnaBridge 181:57724642e740 658 retval = 0;
AnnaBridge 181:57724642e740 659 break;
AnnaBridge 181:57724642e740 660 }
AnnaBridge 181:57724642e740 661
AnnaBridge 181:57724642e740 662 return retval;
AnnaBridge 181:57724642e740 663 }
AnnaBridge 181:57724642e740 664
AnnaBridge 181:57724642e740 665 int i2c_slave_read(i2c_t *obj, char *data, int length) {
AnnaBridge 181:57724642e740 666 int timeout = 0;
AnnaBridge 181:57724642e740 667 int count;
AnnaBridge 181:57724642e740 668 int break_flg = 0;
AnnaBridge 181:57724642e740 669
AnnaBridge 181:57724642e740 670 if(length <= 0) {
AnnaBridge 181:57724642e740 671 return 0;
AnnaBridge 181:57724642e740 672 }
AnnaBridge 181:57724642e740 673 for (count = 0; ((count < (length + 1)) && (break_flg == 0)); count++) {
AnnaBridge 181:57724642e740 674 /* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
AnnaBridge 181:57724642e740 675 while (((i2c_status(obj) & SR2_STOP) != 0) || ((i2c_status(obj) & SR2_RDRF) == 0)) {
AnnaBridge 181:57724642e740 676 if ((i2c_status(obj) & SR2_STOP) != 0) {
AnnaBridge 181:57724642e740 677 break_flg = 1;
AnnaBridge 181:57724642e740 678 break;
AnnaBridge 181:57724642e740 679 }
AnnaBridge 181:57724642e740 680 timeout ++;
AnnaBridge 181:57724642e740 681 if (timeout >= WAIT_TIMEOUT) {
AnnaBridge 181:57724642e740 682 return -1;
AnnaBridge 181:57724642e740 683 }
AnnaBridge 181:57724642e740 684 }
AnnaBridge 181:57724642e740 685 if (break_flg == 0) {
AnnaBridge 181:57724642e740 686 if (count == 0) {
AnnaBridge 181:57724642e740 687 /* dummy read */
AnnaBridge 181:57724642e740 688 (void)REG(DRR.UINT32);
AnnaBridge 181:57724642e740 689 } else {
AnnaBridge 181:57724642e740 690 data[count - 1] = (char)(REG(DRR.UINT32) & 0xFF);
AnnaBridge 181:57724642e740 691 }
AnnaBridge 181:57724642e740 692 }
AnnaBridge 181:57724642e740 693 }
AnnaBridge 181:57724642e740 694 if (break_flg == 0) {
AnnaBridge 181:57724642e740 695 (void)i2c_wait_STOP(obj);
AnnaBridge 181:57724642e740 696 } else {
AnnaBridge 181:57724642e740 697 if ((i2c_status(obj) & SR2_RDRF) != 0) {
AnnaBridge 181:57724642e740 698 if (count <= 1) {
AnnaBridge 181:57724642e740 699 /* fail safe */
AnnaBridge 181:57724642e740 700 /* dummy read */
AnnaBridge 181:57724642e740 701 (void)REG(DRR.UINT32);
AnnaBridge 181:57724642e740 702 } else {
AnnaBridge 181:57724642e740 703 data[count - 2] = (char)(REG(DRR.UINT32) & 0xFF);
AnnaBridge 181:57724642e740 704 }
AnnaBridge 181:57724642e740 705 }
AnnaBridge 181:57724642e740 706 }
AnnaBridge 181:57724642e740 707 /* SR2.STOP = 0 */
AnnaBridge 181:57724642e740 708 REG(SR2.UINT32) &= ~SR2_STOP;
AnnaBridge 181:57724642e740 709
AnnaBridge 181:57724642e740 710 return (count - 1);
AnnaBridge 181:57724642e740 711 }
AnnaBridge 181:57724642e740 712
AnnaBridge 181:57724642e740 713 int i2c_slave_write(i2c_t *obj, const char *data, int length) {
AnnaBridge 181:57724642e740 714 int count = 0;
AnnaBridge 181:57724642e740 715 int status = 0;
AnnaBridge 181:57724642e740 716
AnnaBridge 181:57724642e740 717 if(length <= 0) {
AnnaBridge 181:57724642e740 718 return 0;
AnnaBridge 181:57724642e740 719 }
AnnaBridge 181:57724642e740 720
AnnaBridge 181:57724642e740 721 while ((count < length) && (status == 0)) {
AnnaBridge 181:57724642e740 722 status = i2c_do_write(obj, data[count]);
AnnaBridge 181:57724642e740 723 if(status == 0) {
AnnaBridge 181:57724642e740 724 /* Wait send end */
AnnaBridge 181:57724642e740 725 status = i2c_wait_TEND(obj);
AnnaBridge 181:57724642e740 726 if ((status != 0) || ((count < (length - 1)) && ((REG(SR2.UINT32) & SR2_NACKF) != 0))) {
AnnaBridge 181:57724642e740 727 /* NACK */
AnnaBridge 181:57724642e740 728 break;
AnnaBridge 181:57724642e740 729 }
AnnaBridge 181:57724642e740 730 }
AnnaBridge 181:57724642e740 731 count++;
AnnaBridge 181:57724642e740 732 }
AnnaBridge 181:57724642e740 733 /* dummy read */
AnnaBridge 181:57724642e740 734 (void)REG(DRR.UINT32);
AnnaBridge 181:57724642e740 735 (void)i2c_wait_STOP(obj);
AnnaBridge 181:57724642e740 736 i2c_set_SR2_NACKF_STOP(obj);
AnnaBridge 181:57724642e740 737
AnnaBridge 181:57724642e740 738 return count;
AnnaBridge 181:57724642e740 739 }
AnnaBridge 181:57724642e740 740
AnnaBridge 181:57724642e740 741 void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
AnnaBridge 181:57724642e740 742 REG(SAR0.UINT32) = (address & 0xfffffffe);
AnnaBridge 181:57724642e740 743 }
AnnaBridge 181:57724642e740 744
AnnaBridge 181:57724642e740 745 #if DEVICE_I2C_ASYNCH
AnnaBridge 181:57724642e740 746
AnnaBridge 181:57724642e740 747 #define IRQ_NUM 4
AnnaBridge 181:57724642e740 748 #define IRQ_TX 0
AnnaBridge 181:57724642e740 749 #define IRQ_RX 1
AnnaBridge 181:57724642e740 750 #define IRQ_ERR1 2
AnnaBridge 181:57724642e740 751 #define IRQ_ERR2 3
AnnaBridge 181:57724642e740 752
AnnaBridge 181:57724642e740 753 static void i2c_irqs_set(i2c_t *obj, uint32_t enable);
AnnaBridge 181:57724642e740 754
AnnaBridge 181:57724642e740 755 static void i2c0_tx_irq(void);
AnnaBridge 181:57724642e740 756 static void i2c1_tx_irq(void);
AnnaBridge 181:57724642e740 757 static void i2c2_tx_irq(void);
AnnaBridge 181:57724642e740 758 static void i2c3_tx_irq(void);
AnnaBridge 181:57724642e740 759 static void i2c0_rx_irq(void);
AnnaBridge 181:57724642e740 760 static void i2c1_rx_irq(void);
AnnaBridge 181:57724642e740 761 static void i2c2_rx_irq(void);
AnnaBridge 181:57724642e740 762 static void i2c3_rx_irq(void);
AnnaBridge 181:57724642e740 763 static void i2c0_al_irq(void);
AnnaBridge 181:57724642e740 764 static void i2c1_al_irq(void);
AnnaBridge 181:57724642e740 765 static void i2c2_al_irq(void);
AnnaBridge 181:57724642e740 766 static void i2c3_al_irq(void);
AnnaBridge 181:57724642e740 767 static void i2c0_to_irq(void);
AnnaBridge 181:57724642e740 768 static void i2c1_to_irq(void);
AnnaBridge 181:57724642e740 769 static void i2c2_to_irq(void);
AnnaBridge 181:57724642e740 770 static void i2c3_to_irq(void);
AnnaBridge 181:57724642e740 771
AnnaBridge 181:57724642e740 772 static const IRQn_Type irq_set_tbl[RIIC_COUNT][IRQ_NUM] = {
AnnaBridge 181:57724642e740 773 {INTIICTEI0_IRQn, INTIICRI0_IRQn, INTIICALI0_IRQn, INTIICTMOI0_IRQn},
AnnaBridge 181:57724642e740 774 {INTIICTEI1_IRQn, INTIICRI1_IRQn, INTIICALI1_IRQn, INTIICTMOI1_IRQn},
AnnaBridge 181:57724642e740 775 {INTIICTEI2_IRQn, INTIICRI2_IRQn, INTIICALI2_IRQn, INTIICTMOI2_IRQn},
AnnaBridge 181:57724642e740 776 {INTIICTEI3_IRQn, INTIICRI3_IRQn, INTIICALI3_IRQn, INTIICTMOI3_IRQn},
AnnaBridge 181:57724642e740 777 };
AnnaBridge 181:57724642e740 778
AnnaBridge 181:57724642e740 779 static const IRQHandler hander_set_tbl[RIIC_COUNT][IRQ_NUM] = {
AnnaBridge 181:57724642e740 780 {i2c0_tx_irq, i2c0_rx_irq, i2c0_al_irq, i2c0_to_irq},
AnnaBridge 181:57724642e740 781 {i2c1_tx_irq, i2c1_rx_irq, i2c1_al_irq, i2c1_to_irq},
AnnaBridge 181:57724642e740 782 {i2c2_tx_irq, i2c2_rx_irq, i2c2_al_irq, i2c2_to_irq},
AnnaBridge 181:57724642e740 783 {i2c3_tx_irq, i2c3_rx_irq, i2c3_al_irq, i2c3_to_irq},
AnnaBridge 181:57724642e740 784 };
AnnaBridge 181:57724642e740 785
AnnaBridge 181:57724642e740 786 struct i2c_global_data_s {
AnnaBridge 181:57724642e740 787 i2c_t *async_obj;
AnnaBridge 181:57724642e740 788 uint32_t async_callback, event, shouldStop, address;
AnnaBridge 181:57724642e740 789 };
AnnaBridge 181:57724642e740 790
AnnaBridge 181:57724642e740 791 static struct i2c_global_data_s i2c_data[RIIC_COUNT];
AnnaBridge 181:57724642e740 792
AnnaBridge 181:57724642e740 793 static void i2c_transfer_finished(i2c_t *obj)
AnnaBridge 181:57724642e740 794 {
AnnaBridge 181:57724642e740 795 i2c_irqs_set(obj, 0);
AnnaBridge 181:57724642e740 796 uint32_t index = obj->i2c.i2c;
AnnaBridge 181:57724642e740 797 i2c_data[index].event = I2C_EVENT_TRANSFER_COMPLETE;
AnnaBridge 181:57724642e740 798 i2c_data[index].async_obj = NULL;
AnnaBridge 181:57724642e740 799 ((void (*)())i2c_data[index].async_callback)();
AnnaBridge 181:57724642e740 800 }
AnnaBridge 181:57724642e740 801
AnnaBridge 181:57724642e740 802 static void i2c_tx_irq(IRQn_Type irq_num, uint32_t index)
AnnaBridge 181:57724642e740 803 {
AnnaBridge 181:57724642e740 804 i2c_t *obj = i2c_data[index].async_obj;
AnnaBridge 181:57724642e740 805 if ((REG(SR2.UINT32) & SR2_NACKF)) {
AnnaBridge 181:57724642e740 806 /* Slave sends NACK */
AnnaBridge 181:57724642e740 807 i2c_set_err_noslave(obj);
AnnaBridge 181:57724642e740 808 i2c_data[index].event = I2C_EVENT_ERROR | I2C_EVENT_TRANSFER_EARLY_NACK;
AnnaBridge 181:57724642e740 809 i2c_abort_asynch(obj);
AnnaBridge 181:57724642e740 810 ((void (*)())i2c_data[index].async_callback)();
AnnaBridge 181:57724642e740 811 return;
AnnaBridge 181:57724642e740 812 }
AnnaBridge 181:57724642e740 813 if (obj->tx_buff.pos == obj->tx_buff.length) {
AnnaBridge 181:57724642e740 814 /* All datas have tranferred */
AnnaBridge 181:57724642e740 815
AnnaBridge 181:57724642e740 816 /* Clear TEND */
AnnaBridge 181:57724642e740 817 REG(SR2.UINT32) &= ~(SR2_TEND);
AnnaBridge 181:57724642e740 818
AnnaBridge 181:57724642e740 819 /* If not repeated start, send stop. */
AnnaBridge 181:57724642e740 820 if (i2c_data[index].shouldStop && obj->rx_buff.length == 0) {
AnnaBridge 181:57724642e740 821 (void)i2c_set_STOP(obj);
AnnaBridge 181:57724642e740 822 (void)i2c_wait_STOP(obj);
AnnaBridge 181:57724642e740 823 i2c_set_SR2_NACKF_STOP(obj);
AnnaBridge 181:57724642e740 824 i2c_transfer_finished(obj);
AnnaBridge 181:57724642e740 825 } else {
AnnaBridge 181:57724642e740 826 (void)i2c_restart(obj);
AnnaBridge 181:57724642e740 827 (void)i2c_wait_START(obj);
AnnaBridge 181:57724642e740 828 /* SR2.START = 0 */
AnnaBridge 181:57724642e740 829 REG(SR2.UINT32) &= ~SR2_START;
AnnaBridge 181:57724642e740 830 if (obj->rx_buff.length) {
AnnaBridge 181:57724642e740 831 /* Ready to read */
AnnaBridge 181:57724642e740 832 i2c_set_MR3_ACK(obj);
AnnaBridge 181:57724642e740 833
AnnaBridge 181:57724642e740 834 /* Disable INTRIICTEI */
AnnaBridge 181:57724642e740 835 REG(IER.UINT8[0]) &= ~(1 << 6);
AnnaBridge 181:57724642e740 836
AnnaBridge 181:57724642e740 837 /* Send Slave address */
AnnaBridge 181:57724642e740 838 if (i2c_read_address_write(obj, (i2c_data[index].address | 0x01)) != 0) {
AnnaBridge 181:57724642e740 839 i2c_set_err_noslave(obj);
AnnaBridge 181:57724642e740 840 i2c_data[index].event = I2C_EVENT_ERROR | I2C_EVENT_ERROR_NO_SLAVE;
AnnaBridge 181:57724642e740 841 i2c_abort_asynch(obj);
AnnaBridge 181:57724642e740 842 ((void (*)())i2c_data[index].async_callback)();
AnnaBridge 181:57724642e740 843 return;
AnnaBridge 181:57724642e740 844 }
AnnaBridge 181:57724642e740 845 } else {
AnnaBridge 181:57724642e740 846 i2c_transfer_finished(obj);
AnnaBridge 181:57724642e740 847 }
AnnaBridge 181:57724642e740 848 }
AnnaBridge 181:57724642e740 849 } else {
AnnaBridge 181:57724642e740 850 /* Send next 1 byte */
AnnaBridge 181:57724642e740 851 if (i2c_do_write(obj, *(uint8_t *)obj->tx_buff.buffer) != 0) {
AnnaBridge 181:57724642e740 852 i2c_set_err_noslave(obj);
AnnaBridge 181:57724642e740 853 i2c_data[index].event = I2C_EVENT_ERROR | I2C_EVENT_ERROR_NO_SLAVE;
AnnaBridge 181:57724642e740 854 i2c_abort_asynch(obj);
AnnaBridge 181:57724642e740 855 ((void (*)())i2c_data[index].async_callback)();
AnnaBridge 181:57724642e740 856 return;
AnnaBridge 181:57724642e740 857 }
AnnaBridge 181:57724642e740 858 obj->tx_buff.buffer = (uint8_t *)obj->tx_buff.buffer + 1;
AnnaBridge 181:57724642e740 859 ++obj->tx_buff.pos;
AnnaBridge 181:57724642e740 860 }
AnnaBridge 181:57724642e740 861 }
AnnaBridge 181:57724642e740 862
AnnaBridge 181:57724642e740 863 static void i2c_rx_irq(IRQn_Type irq_num, uint32_t index)
AnnaBridge 181:57724642e740 864 {
AnnaBridge 181:57724642e740 865 i2c_t *obj = i2c_data[index].async_obj;
AnnaBridge 181:57724642e740 866 if (obj->rx_buff.pos == SIZE_MAX) {
AnnaBridge 181:57724642e740 867 if ((REG(SR2.UINT32) & SR2_NACKF) != 0) {
AnnaBridge 181:57724642e740 868 /* Slave sends NACK */
AnnaBridge 181:57724642e740 869 (void)i2c_set_STOP(obj);
AnnaBridge 181:57724642e740 870 /* dummy read */
AnnaBridge 181:57724642e740 871 if (REG(DRR.UINT32)) {}
AnnaBridge 181:57724642e740 872 (void)i2c_wait_STOP(obj);
AnnaBridge 181:57724642e740 873 i2c_set_SR2_NACKF_STOP(obj);
AnnaBridge 181:57724642e740 874 obj->i2c.last_stop_flag = 1;
AnnaBridge 181:57724642e740 875
AnnaBridge 181:57724642e740 876 i2c_data[index].event = I2C_EVENT_ERROR | I2C_EVENT_TRANSFER_EARLY_NACK;
AnnaBridge 181:57724642e740 877 i2c_abort_asynch(obj);
AnnaBridge 181:57724642e740 878 ((void (*)())i2c_data[index].async_callback)();
AnnaBridge 181:57724642e740 879 return;
AnnaBridge 181:57724642e740 880 }
AnnaBridge 181:57724642e740 881 if (obj->rx_buff.length == 1) {
AnnaBridge 181:57724642e740 882 /* length == 1 */
AnnaBridge 181:57724642e740 883 /* Set MR3 WAIT bit is 1 */;
AnnaBridge 181:57724642e740 884 REG(MR3.UINT32) |= MR3_WAIT;
AnnaBridge 181:57724642e740 885 i2c_set_MR3_NACK(obj);
AnnaBridge 181:57724642e740 886 } else if (obj->rx_buff.length == 2) {
AnnaBridge 181:57724642e740 887 /* Set MR3 WAIT bit is 1 */
AnnaBridge 181:57724642e740 888 REG(MR3.UINT32) |= MR3_WAIT;
AnnaBridge 181:57724642e740 889 }
AnnaBridge 181:57724642e740 890 /* dummy read */
AnnaBridge 181:57724642e740 891 if (REG(DRR.UINT32)) {}
AnnaBridge 181:57724642e740 892 obj->rx_buff.pos = 0;
AnnaBridge 181:57724642e740 893 return;
AnnaBridge 181:57724642e740 894 }
AnnaBridge 181:57724642e740 895 if ((REG(SR2.UINT32) & SR2_NACKF) != 0) {
AnnaBridge 181:57724642e740 896 /* Slave sends NACK */
AnnaBridge 181:57724642e740 897 i2c_set_err_noslave(obj);
AnnaBridge 181:57724642e740 898 i2c_data[index].event = I2C_EVENT_ERROR | I2C_EVENT_TRANSFER_EARLY_NACK;
AnnaBridge 181:57724642e740 899 i2c_abort_asynch(obj);
AnnaBridge 181:57724642e740 900 ((void (*)())i2c_data[index].async_callback)();
AnnaBridge 181:57724642e740 901 return;
AnnaBridge 181:57724642e740 902 } else {
AnnaBridge 181:57724642e740 903 switch (obj->rx_buff.length - obj->rx_buff.pos) {
AnnaBridge 181:57724642e740 904 case 1:
AnnaBridge 181:57724642e740 905 /* Finished */
AnnaBridge 181:57724642e740 906 /* If not repeated start, send stop. */
AnnaBridge 181:57724642e740 907 if (i2c_data[index].shouldStop) {
AnnaBridge 181:57724642e740 908 (void)i2c_set_STOP(obj);
AnnaBridge 181:57724642e740 909 /* RIICnDRR read */
AnnaBridge 181:57724642e740 910 *(uint8_t *)obj->rx_buff.buffer = REG(DRR.UINT32) & 0xFF;
AnnaBridge 181:57724642e740 911 /* RIICnMR3.WAIT = 0 */
AnnaBridge 181:57724642e740 912 REG(MR3.UINT32) &= ~MR3_WAIT;
AnnaBridge 181:57724642e740 913 (void)i2c_wait_STOP(obj);
AnnaBridge 181:57724642e740 914 i2c_set_SR2_NACKF_STOP(obj);
AnnaBridge 181:57724642e740 915 } else {
AnnaBridge 181:57724642e740 916 (void)i2c_restart(obj);
AnnaBridge 181:57724642e740 917 /* RIICnDRR read */
AnnaBridge 181:57724642e740 918 *(uint8_t *)obj->rx_buff.buffer = REG(DRR.UINT32) & 0xFF;
AnnaBridge 181:57724642e740 919 /* RIICnMR3.WAIT = 0 */
AnnaBridge 181:57724642e740 920 REG(MR3.UINT32) &= ~MR3_WAIT;
AnnaBridge 181:57724642e740 921 (void)i2c_wait_START(obj);
AnnaBridge 181:57724642e740 922 /* SR2.START = 0 */
AnnaBridge 181:57724642e740 923 REG(SR2.UINT32) &= ~SR2_START;
AnnaBridge 181:57724642e740 924 }
AnnaBridge 181:57724642e740 925
AnnaBridge 181:57724642e740 926 i2c_transfer_finished(obj);
AnnaBridge 181:57724642e740 927 return;
AnnaBridge 181:57724642e740 928
AnnaBridge 181:57724642e740 929 case 2:
AnnaBridge 181:57724642e740 930 i2c_set_MR3_NACK(obj);
AnnaBridge 181:57724642e740 931 break;
AnnaBridge 181:57724642e740 932
AnnaBridge 181:57724642e740 933 case 3:
AnnaBridge 181:57724642e740 934 /* this time is befor last byte read */
AnnaBridge 181:57724642e740 935 /* Set MR3 WAIT bit is 1 */
AnnaBridge 181:57724642e740 936 REG(MR3.UINT32) |= MR3_WAIT;
AnnaBridge 181:57724642e740 937 break;
AnnaBridge 181:57724642e740 938
AnnaBridge 181:57724642e740 939 default:
AnnaBridge 181:57724642e740 940 i2c_set_MR3_ACK(obj);
AnnaBridge 181:57724642e740 941 break;
AnnaBridge 181:57724642e740 942 }
AnnaBridge 181:57724642e740 943 *(uint8_t *)obj->rx_buff.buffer = REG(DRR.UINT32) & 0xFF;
AnnaBridge 181:57724642e740 944 obj->rx_buff.buffer = (uint8_t *)obj->rx_buff.buffer + 1;
AnnaBridge 181:57724642e740 945 ++obj->rx_buff.pos;
AnnaBridge 181:57724642e740 946 }
AnnaBridge 181:57724642e740 947 }
AnnaBridge 181:57724642e740 948
AnnaBridge 181:57724642e740 949 static void i2c_err_irq(IRQn_Type irq_num, uint32_t index)
AnnaBridge 181:57724642e740 950 {
AnnaBridge 181:57724642e740 951 i2c_t *obj = i2c_data[index].async_obj;
AnnaBridge 181:57724642e740 952 i2c_abort_asynch(obj);
AnnaBridge 181:57724642e740 953 i2c_data[index].event = I2C_EVENT_ERROR;
AnnaBridge 181:57724642e740 954 ((void (*)())i2c_data[index].async_callback)();
AnnaBridge 181:57724642e740 955 }
AnnaBridge 181:57724642e740 956
AnnaBridge 181:57724642e740 957 /* TX handler */
AnnaBridge 181:57724642e740 958 static void i2c0_tx_irq(void)
AnnaBridge 181:57724642e740 959 {
AnnaBridge 181:57724642e740 960 i2c_tx_irq(INTIICTEI0_IRQn, 0);
AnnaBridge 181:57724642e740 961 }
AnnaBridge 181:57724642e740 962
AnnaBridge 181:57724642e740 963 static void i2c1_tx_irq(void)
AnnaBridge 181:57724642e740 964 {
AnnaBridge 181:57724642e740 965 i2c_tx_irq(INTIICTEI1_IRQn, 1);
AnnaBridge 181:57724642e740 966 }
AnnaBridge 181:57724642e740 967
AnnaBridge 181:57724642e740 968 static void i2c2_tx_irq(void)
AnnaBridge 181:57724642e740 969 {
AnnaBridge 181:57724642e740 970 i2c_tx_irq(INTIICTEI2_IRQn, 2);
AnnaBridge 181:57724642e740 971 }
AnnaBridge 181:57724642e740 972
AnnaBridge 181:57724642e740 973 static void i2c3_tx_irq(void)
AnnaBridge 181:57724642e740 974 {
AnnaBridge 181:57724642e740 975 i2c_tx_irq(INTIICTEI3_IRQn, 3);
AnnaBridge 181:57724642e740 976 }
AnnaBridge 181:57724642e740 977
AnnaBridge 181:57724642e740 978 /* RX handler */
AnnaBridge 181:57724642e740 979 static void i2c0_rx_irq(void)
AnnaBridge 181:57724642e740 980 {
AnnaBridge 181:57724642e740 981 i2c_rx_irq(INTIICRI0_IRQn, 0);
AnnaBridge 181:57724642e740 982 }
AnnaBridge 181:57724642e740 983
AnnaBridge 181:57724642e740 984 static void i2c1_rx_irq(void)
AnnaBridge 181:57724642e740 985 {
AnnaBridge 181:57724642e740 986 i2c_rx_irq(INTIICRI1_IRQn, 1);
AnnaBridge 181:57724642e740 987 }
AnnaBridge 181:57724642e740 988
AnnaBridge 181:57724642e740 989 static void i2c2_rx_irq(void)
AnnaBridge 181:57724642e740 990 {
AnnaBridge 181:57724642e740 991 i2c_rx_irq(INTIICRI2_IRQn, 2);
AnnaBridge 181:57724642e740 992 }
AnnaBridge 181:57724642e740 993
AnnaBridge 181:57724642e740 994 static void i2c3_rx_irq(void)
AnnaBridge 181:57724642e740 995 {
AnnaBridge 181:57724642e740 996 i2c_rx_irq(INTIICRI3_IRQn, 3);
AnnaBridge 181:57724642e740 997 }
AnnaBridge 181:57724642e740 998
AnnaBridge 181:57724642e740 999 /* Arbitration Lost handler */
AnnaBridge 181:57724642e740 1000 static void i2c0_al_irq(void)
AnnaBridge 181:57724642e740 1001 {
AnnaBridge 181:57724642e740 1002 i2c_err_irq(INTIICALI0_IRQn, 0);
AnnaBridge 181:57724642e740 1003 }
AnnaBridge 181:57724642e740 1004
AnnaBridge 181:57724642e740 1005 static void i2c1_al_irq(void)
AnnaBridge 181:57724642e740 1006 {
AnnaBridge 181:57724642e740 1007 i2c_err_irq(INTIICALI1_IRQn, 1);
AnnaBridge 181:57724642e740 1008 }
AnnaBridge 181:57724642e740 1009
AnnaBridge 181:57724642e740 1010 static void i2c2_al_irq(void)
AnnaBridge 181:57724642e740 1011 {
AnnaBridge 181:57724642e740 1012 i2c_err_irq(INTIICALI2_IRQn, 2);
AnnaBridge 181:57724642e740 1013 }
AnnaBridge 181:57724642e740 1014
AnnaBridge 181:57724642e740 1015 static void i2c3_al_irq(void)
AnnaBridge 181:57724642e740 1016 {
AnnaBridge 181:57724642e740 1017 i2c_err_irq(INTIICALI3_IRQn, 3);
AnnaBridge 181:57724642e740 1018 }
AnnaBridge 181:57724642e740 1019
AnnaBridge 181:57724642e740 1020 /* Timeout handler */
AnnaBridge 181:57724642e740 1021 static void i2c0_to_irq(void)
AnnaBridge 181:57724642e740 1022 {
AnnaBridge 181:57724642e740 1023 i2c_err_irq(INTIICTMOI0_IRQn, 0);
AnnaBridge 181:57724642e740 1024 }
AnnaBridge 181:57724642e740 1025
AnnaBridge 181:57724642e740 1026 static void i2c1_to_irq(void)
AnnaBridge 181:57724642e740 1027 {
AnnaBridge 181:57724642e740 1028 i2c_err_irq(INTIICTMOI1_IRQn, 1);
AnnaBridge 181:57724642e740 1029 }
AnnaBridge 181:57724642e740 1030
AnnaBridge 181:57724642e740 1031 static void i2c2_to_irq(void)
AnnaBridge 181:57724642e740 1032 {
AnnaBridge 181:57724642e740 1033 i2c_err_irq(INTIICTMOI2_IRQn, 2);
AnnaBridge 181:57724642e740 1034 }
AnnaBridge 181:57724642e740 1035
AnnaBridge 181:57724642e740 1036 static void i2c3_to_irq(void)
AnnaBridge 181:57724642e740 1037 {
AnnaBridge 181:57724642e740 1038 i2c_err_irq(INTIICTMOI3_IRQn, 3);
AnnaBridge 181:57724642e740 1039 }
AnnaBridge 181:57724642e740 1040
AnnaBridge 181:57724642e740 1041 static void i2c_irqs_set(i2c_t *obj, uint32_t enable)
AnnaBridge 181:57724642e740 1042 {
AnnaBridge 181:57724642e740 1043 int i;
AnnaBridge 181:57724642e740 1044 const IRQn_Type *irqTable = irq_set_tbl[obj->i2c.i2c];
AnnaBridge 181:57724642e740 1045 const IRQHandler *handlerTable = hander_set_tbl[obj->i2c.i2c];
AnnaBridge 181:57724642e740 1046 for (i = 0; i < IRQ_NUM; ++i) {
AnnaBridge 181:57724642e740 1047 if (enable) {
AnnaBridge 181:57724642e740 1048 InterruptHandlerRegister(irqTable[i], handlerTable[i]);
AnnaBridge 181:57724642e740 1049 GIC_SetPriority(irqTable[i], 5);
AnnaBridge 181:57724642e740 1050 if (i == 1) {
AnnaBridge 181:57724642e740 1051 GIC_SetConfiguration(irqTable[i], 3);
AnnaBridge 181:57724642e740 1052 } else {
AnnaBridge 181:57724642e740 1053 GIC_SetConfiguration(irqTable[i], 1);
AnnaBridge 181:57724642e740 1054 }
AnnaBridge 181:57724642e740 1055 GIC_EnableIRQ(irqTable[i]);
AnnaBridge 181:57724642e740 1056 } else {
AnnaBridge 181:57724642e740 1057 GIC_DisableIRQ(irqTable[i]);
AnnaBridge 181:57724642e740 1058 }
AnnaBridge 181:57724642e740 1059 }
AnnaBridge 181:57724642e740 1060 REG(IER.UINT8[0]) = enable ? 0x63 : 0x00;
AnnaBridge 181:57724642e740 1061 }
AnnaBridge 181:57724642e740 1062
AnnaBridge 181:57724642e740 1063 /******************************************************************************
AnnaBridge 181:57724642e740 1064 * ASYNCHRONOUS HAL
AnnaBridge 181:57724642e740 1065 ******************************************************************************/
AnnaBridge 181:57724642e740 1066
AnnaBridge 181:57724642e740 1067 void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint32_t address, uint32_t stop, uint32_t handler, uint32_t event, DMAUsage hint)
AnnaBridge 181:57724642e740 1068 {
AnnaBridge 181:57724642e740 1069 MBED_ASSERT(obj);
AnnaBridge 181:57724642e740 1070 MBED_ASSERT(tx ? tx_length : 1);
AnnaBridge 181:57724642e740 1071 MBED_ASSERT(rx ? rx_length : 1);
AnnaBridge 181:57724642e740 1072 MBED_ASSERT((REG(SER.UINT32) & SER_SAR0E) == 0); /* Slave mode */
AnnaBridge 181:57724642e740 1073
AnnaBridge 181:57724642e740 1074 obj->tx_buff.buffer = (void *)tx;
AnnaBridge 181:57724642e740 1075 obj->tx_buff.length = tx_length;
AnnaBridge 181:57724642e740 1076 obj->tx_buff.pos = 0;
AnnaBridge 181:57724642e740 1077 obj->tx_buff.width = 8;
AnnaBridge 181:57724642e740 1078 obj->rx_buff.buffer = rx;
AnnaBridge 181:57724642e740 1079 obj->rx_buff.length = rx_length;
AnnaBridge 181:57724642e740 1080 obj->rx_buff.pos = SIZE_MAX;
AnnaBridge 181:57724642e740 1081 obj->rx_buff.width = 8;
AnnaBridge 181:57724642e740 1082 i2c_data[obj->i2c.i2c].async_obj = obj;
AnnaBridge 181:57724642e740 1083 i2c_data[obj->i2c.i2c].async_callback = handler;
AnnaBridge 181:57724642e740 1084 i2c_data[obj->i2c.i2c].event = 0;
AnnaBridge 181:57724642e740 1085 i2c_data[obj->i2c.i2c].shouldStop = stop;
AnnaBridge 181:57724642e740 1086 i2c_data[obj->i2c.i2c].address = address;
AnnaBridge 181:57724642e740 1087 i2c_irqs_set(obj, 1);
AnnaBridge 181:57724642e740 1088
AnnaBridge 181:57724642e740 1089 /* There is a STOP condition for last processing */
AnnaBridge 181:57724642e740 1090 if (obj->i2c.last_stop_flag != 0) {
AnnaBridge 181:57724642e740 1091 if (i2c_start(obj) != 0) {
AnnaBridge 181:57724642e740 1092 i2c_set_err_noslave(obj);
AnnaBridge 181:57724642e740 1093 i2c_data[obj->i2c.i2c].event = I2C_EVENT_ERROR | I2C_EVENT_ERROR_NO_SLAVE;
AnnaBridge 181:57724642e740 1094 i2c_abort_asynch(obj);
AnnaBridge 181:57724642e740 1095 ((void (*)())handler)();
AnnaBridge 181:57724642e740 1096 return;
AnnaBridge 181:57724642e740 1097 }
AnnaBridge 181:57724642e740 1098 }
AnnaBridge 181:57724642e740 1099 obj->i2c.last_stop_flag = stop;
AnnaBridge 181:57724642e740 1100
AnnaBridge 181:57724642e740 1101 if (rx_length && tx_length == 0) {
AnnaBridge 181:57724642e740 1102 /* Ready to read */
AnnaBridge 181:57724642e740 1103 i2c_set_MR3_ACK(obj);
AnnaBridge 181:57724642e740 1104
AnnaBridge 181:57724642e740 1105 /* Disable INTRIICTEI */
AnnaBridge 181:57724642e740 1106 REG(IER.UINT8[0]) &= ~(1 << 6);
AnnaBridge 181:57724642e740 1107
AnnaBridge 181:57724642e740 1108 address |= 0x01;
AnnaBridge 181:57724642e740 1109 }
AnnaBridge 181:57724642e740 1110 /* Send Slave address */
AnnaBridge 181:57724642e740 1111 if (i2c_do_write(obj, address) != 0) {
AnnaBridge 181:57724642e740 1112 i2c_set_err_noslave(obj);
AnnaBridge 181:57724642e740 1113 i2c_data[obj->i2c.i2c].event = I2C_EVENT_ERROR | I2C_EVENT_ERROR_NO_SLAVE;
AnnaBridge 181:57724642e740 1114 i2c_abort_asynch(obj);
AnnaBridge 181:57724642e740 1115 ((void (*)())handler)();
AnnaBridge 181:57724642e740 1116 return;
AnnaBridge 181:57724642e740 1117 }
AnnaBridge 181:57724642e740 1118 }
AnnaBridge 181:57724642e740 1119
AnnaBridge 181:57724642e740 1120 uint32_t i2c_irq_handler_asynch(i2c_t *obj)
AnnaBridge 181:57724642e740 1121 {
AnnaBridge 181:57724642e740 1122 return i2c_data[obj->i2c.i2c].event;
AnnaBridge 181:57724642e740 1123 }
AnnaBridge 181:57724642e740 1124
AnnaBridge 181:57724642e740 1125 uint8_t i2c_active(i2c_t *obj)
AnnaBridge 181:57724642e740 1126 {
AnnaBridge 181:57724642e740 1127 return i2c_data[obj->i2c.i2c].async_obj != NULL;
AnnaBridge 181:57724642e740 1128 }
AnnaBridge 181:57724642e740 1129
AnnaBridge 181:57724642e740 1130 void i2c_abort_asynch(i2c_t *obj)
AnnaBridge 181:57724642e740 1131 {
AnnaBridge 181:57724642e740 1132 i2c_data[obj->i2c.i2c].async_obj = NULL;
AnnaBridge 181:57724642e740 1133 i2c_irqs_set(obj, 0);
AnnaBridge 181:57724642e740 1134 i2c_reg_reset(obj);
AnnaBridge 181:57724642e740 1135 }
AnnaBridge 181:57724642e740 1136
AnnaBridge 181:57724642e740 1137 #endif