Daiki Kato / mbed-os-lychee

Dependents:   mbed-os-example-blinky-gr-lychee GR-Boads_Camera_sample GR-Boards_Audio_Recoder GR-Boads_Camera_DisplayApp ... more

Committer:
dkato
Date:
Fri Feb 02 05:42:23 2018 +0000
Revision:
0:f782d9c66c49
mbed-os for GR-LYCHEE

Who changed what in which revision?

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