added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
JojoS
Date:
Sat Sep 10 15:32:04 2016 +0000
Revision:
147:ba84b7dc41a7
Parent:
144:ef7eb2e8f9f7
added prescaler for 16 bit timers (solution as in LPC11xx), default prescaler 31 for max 28 ms period time

Who changed what in which revision?

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