added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
mbed_official
Date:
Fri Apr 29 01:15:11 2016 +0100
Revision:
119:3921aeca8633
Parent:
0:9b334a45a8ff
Child:
144:ef7eb2e8f9f7
Synchronized with git revision fe9720f24b1adc71ab6962506ec51290f6afd270

Full URL: https://github.com/mbedmicro/mbed/commit/fe9720f24b1adc71ab6962506ec51290f6afd270/

[Renesas RZ/A1H] Enable asynchronous communications

Who changed what in which revision?

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