Mouse code for the MacroRat

Dependencies:   ITG3200 QEI

Committer:
sahilmgandhi
Date:
Sun May 14 23:18:57 2017 +0000
Revision:
18:6a4db94011d3
Publishing again

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sahilmgandhi 18:6a4db94011d3 1 /* mbed Microcontroller Library
sahilmgandhi 18:6a4db94011d3 2 * Copyright (c) 2006-2013 ARM Limited
sahilmgandhi 18:6a4db94011d3 3 *
sahilmgandhi 18:6a4db94011d3 4 * Licensed under the Apache License, Version 2.0 (the "License");
sahilmgandhi 18:6a4db94011d3 5 * you may not use this file except in compliance with the License.
sahilmgandhi 18:6a4db94011d3 6 * You may obtain a copy of the License at
sahilmgandhi 18:6a4db94011d3 7 *
sahilmgandhi 18:6a4db94011d3 8 * http://www.apache.org/licenses/LICENSE-2.0
sahilmgandhi 18:6a4db94011d3 9 *
sahilmgandhi 18:6a4db94011d3 10 * Unless required by applicable law or agreed to in writing, software
sahilmgandhi 18:6a4db94011d3 11 * distributed under the License is distributed on an "AS IS" BASIS,
sahilmgandhi 18:6a4db94011d3 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
sahilmgandhi 18:6a4db94011d3 13 * See the License for the specific language governing permissions and
sahilmgandhi 18:6a4db94011d3 14 * limitations under the License.
sahilmgandhi 18:6a4db94011d3 15 */
sahilmgandhi 18:6a4db94011d3 16 #include "mbed_assert.h"
sahilmgandhi 18:6a4db94011d3 17 #include "i2c_api.h"
sahilmgandhi 18:6a4db94011d3 18 #include "cmsis.h"
sahilmgandhi 18:6a4db94011d3 19 #include "pinmap.h"
sahilmgandhi 18:6a4db94011d3 20 #include "r_typedefs.h"
sahilmgandhi 18:6a4db94011d3 21
sahilmgandhi 18:6a4db94011d3 22 #include "riic_iodefine.h"
sahilmgandhi 18:6a4db94011d3 23 #include "RZ_A1_Init.h"
sahilmgandhi 18:6a4db94011d3 24 #include "VKRZA1H.h"
sahilmgandhi 18:6a4db94011d3 25
sahilmgandhi 18:6a4db94011d3 26 volatile struct st_riic *RIIC[] = RIIC_ADDRESS_LIST;
sahilmgandhi 18:6a4db94011d3 27
sahilmgandhi 18:6a4db94011d3 28 #define REG(N) \
sahilmgandhi 18:6a4db94011d3 29 RIIC[obj->i2c]->RIICn##N
sahilmgandhi 18:6a4db94011d3 30
sahilmgandhi 18:6a4db94011d3 31 /* RIICnCR1 */
sahilmgandhi 18:6a4db94011d3 32 #define CR1_RST (1 << 6)
sahilmgandhi 18:6a4db94011d3 33 #define CR1_ICE (1 << 7)
sahilmgandhi 18:6a4db94011d3 34
sahilmgandhi 18:6a4db94011d3 35 /* RIICnCR2 */
sahilmgandhi 18:6a4db94011d3 36 #define CR2_ST (1 << 1)
sahilmgandhi 18:6a4db94011d3 37 #define CR2_RS (1 << 2)
sahilmgandhi 18:6a4db94011d3 38 #define CR2_SP (1 << 3)
sahilmgandhi 18:6a4db94011d3 39 #define CR2_TRS (1 << 5)
sahilmgandhi 18:6a4db94011d3 40 #define CR2_BBSY (1 << 7)
sahilmgandhi 18:6a4db94011d3 41
sahilmgandhi 18:6a4db94011d3 42 /* RIICnMR3 */
sahilmgandhi 18:6a4db94011d3 43 #define MR3_ACKBT (1 << 3)
sahilmgandhi 18:6a4db94011d3 44 #define MR3_ACKWP (1 << 4)
sahilmgandhi 18:6a4db94011d3 45 #define MR3_WAIT (1 << 6)
sahilmgandhi 18:6a4db94011d3 46
sahilmgandhi 18:6a4db94011d3 47 /* RIICnSER */
sahilmgandhi 18:6a4db94011d3 48 #define SER_SAR0E (1 << 0)
sahilmgandhi 18:6a4db94011d3 49
sahilmgandhi 18:6a4db94011d3 50 /* RIICnSR1 */
sahilmgandhi 18:6a4db94011d3 51 #define SR1_AAS0 (1 << 0)
sahilmgandhi 18:6a4db94011d3 52
sahilmgandhi 18:6a4db94011d3 53 /* RIICnSR2 */
sahilmgandhi 18:6a4db94011d3 54 #define SR2_START (1 << 2)
sahilmgandhi 18:6a4db94011d3 55 #define SR2_STOP (1 << 3)
sahilmgandhi 18:6a4db94011d3 56 #define SR2_NACKF (1 << 4)
sahilmgandhi 18:6a4db94011d3 57 #define SR2_RDRF (1 << 5)
sahilmgandhi 18:6a4db94011d3 58 #define SR2_TEND (1 << 6)
sahilmgandhi 18:6a4db94011d3 59 #define SR2_TDRE (1 << 7)
sahilmgandhi 18:6a4db94011d3 60
sahilmgandhi 18:6a4db94011d3 61 #define WAIT_TIMEOUT (3600000) /* Loop counter : Time-out is about 1s. By 3600000 loops, measured value is 969ms. */
sahilmgandhi 18:6a4db94011d3 62
sahilmgandhi 18:6a4db94011d3 63 static const PinMap PinMap_I2C_SDA[] = {
sahilmgandhi 18:6a4db94011d3 64 {P1_1 , I2C_0, 1},
sahilmgandhi 18:6a4db94011d3 65 {P1_3 , I2C_1, 1},
sahilmgandhi 18:6a4db94011d3 66 {P1_5 , I2C_2, 1},
sahilmgandhi 18:6a4db94011d3 67 {P1_7 , I2C_3, 1},
sahilmgandhi 18:6a4db94011d3 68 {NC , NC , 0}
sahilmgandhi 18:6a4db94011d3 69 };
sahilmgandhi 18:6a4db94011d3 70
sahilmgandhi 18:6a4db94011d3 71 static const PinMap PinMap_I2C_SCL[] = {
sahilmgandhi 18:6a4db94011d3 72 {P1_0 , I2C_0, 1},
sahilmgandhi 18:6a4db94011d3 73 {P1_2 , I2C_1, 1},
sahilmgandhi 18:6a4db94011d3 74 {P1_4 , I2C_2, 1},
sahilmgandhi 18:6a4db94011d3 75 {P1_6 , I2C_3, 1},
sahilmgandhi 18:6a4db94011d3 76 {NC , NC, 0}
sahilmgandhi 18:6a4db94011d3 77 };
sahilmgandhi 18:6a4db94011d3 78
sahilmgandhi 18:6a4db94011d3 79
sahilmgandhi 18:6a4db94011d3 80 static inline int i2c_status(i2c_t *obj) {
sahilmgandhi 18:6a4db94011d3 81 return REG(SR2.UINT8[0]);
sahilmgandhi 18:6a4db94011d3 82 }
sahilmgandhi 18:6a4db94011d3 83
sahilmgandhi 18:6a4db94011d3 84 static void i2c_reg_reset(i2c_t *obj) {
sahilmgandhi 18:6a4db94011d3 85 /* full reset */
sahilmgandhi 18:6a4db94011d3 86 REG(CR1.UINT8[0]) &= ~CR1_ICE; // CR1.ICE off
sahilmgandhi 18:6a4db94011d3 87 REG(CR1.UINT8[0]) |= CR1_RST; // CR1.IICRST on
sahilmgandhi 18:6a4db94011d3 88 REG(CR1.UINT8[0]) |= CR1_ICE; // CR1.ICE on
sahilmgandhi 18:6a4db94011d3 89
sahilmgandhi 18:6a4db94011d3 90 REG(MR1.UINT8[0]) = 0x08; // P_phi /x 9bit (including Ack)
sahilmgandhi 18:6a4db94011d3 91 REG(SER.UINT8[0]) = 0x00; // no slave addr enabled
sahilmgandhi 18:6a4db94011d3 92
sahilmgandhi 18:6a4db94011d3 93 /* set frequency */
sahilmgandhi 18:6a4db94011d3 94 REG(MR1.UINT8[0]) |= obj->pclk_bit;
sahilmgandhi 18:6a4db94011d3 95 REG(BRL.UINT8[0]) = obj->width_low;
sahilmgandhi 18:6a4db94011d3 96 REG(BRH.UINT8[0]) = obj->width_hi;
sahilmgandhi 18:6a4db94011d3 97
sahilmgandhi 18:6a4db94011d3 98 REG(MR2.UINT8[0]) = 0x07;
sahilmgandhi 18:6a4db94011d3 99 REG(MR3.UINT8[0]) = 0x00;
sahilmgandhi 18:6a4db94011d3 100
sahilmgandhi 18:6a4db94011d3 101 REG(FER.UINT8[0]) = 0x72; // SCLE, NFE enabled, TMOT
sahilmgandhi 18:6a4db94011d3 102 REG(IER.UINT8[0]) = 0x00; // no interrupt
sahilmgandhi 18:6a4db94011d3 103
sahilmgandhi 18:6a4db94011d3 104 REG(CR1.UINT32) &= ~CR1_RST; // CR1.IICRST negate reset
sahilmgandhi 18:6a4db94011d3 105 }
sahilmgandhi 18:6a4db94011d3 106
sahilmgandhi 18:6a4db94011d3 107 static inline int i2c_wait_RDRF(i2c_t *obj) {
sahilmgandhi 18:6a4db94011d3 108 int timeout = 0;
sahilmgandhi 18:6a4db94011d3 109
sahilmgandhi 18:6a4db94011d3 110 /* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
sahilmgandhi 18:6a4db94011d3 111 while ((i2c_status(obj) & SR2_RDRF) == 0) {
sahilmgandhi 18:6a4db94011d3 112 timeout ++;
sahilmgandhi 18:6a4db94011d3 113 if (timeout >= WAIT_TIMEOUT) {
sahilmgandhi 18:6a4db94011d3 114 return -1;
sahilmgandhi 18:6a4db94011d3 115 }
sahilmgandhi 18:6a4db94011d3 116 }
sahilmgandhi 18:6a4db94011d3 117
sahilmgandhi 18:6a4db94011d3 118 return 0;
sahilmgandhi 18:6a4db94011d3 119 }
sahilmgandhi 18:6a4db94011d3 120
sahilmgandhi 18:6a4db94011d3 121 static int i2c_wait_TDRE(i2c_t *obj) {
sahilmgandhi 18:6a4db94011d3 122 int timeout = 0;
sahilmgandhi 18:6a4db94011d3 123
sahilmgandhi 18:6a4db94011d3 124 /* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
sahilmgandhi 18:6a4db94011d3 125 while ((i2c_status(obj) & SR2_TDRE) == 0) {
sahilmgandhi 18:6a4db94011d3 126 timeout ++;
sahilmgandhi 18:6a4db94011d3 127 if (timeout >= WAIT_TIMEOUT) {
sahilmgandhi 18:6a4db94011d3 128 return -1;
sahilmgandhi 18:6a4db94011d3 129 }
sahilmgandhi 18:6a4db94011d3 130 }
sahilmgandhi 18:6a4db94011d3 131
sahilmgandhi 18:6a4db94011d3 132 return 0;
sahilmgandhi 18:6a4db94011d3 133 }
sahilmgandhi 18:6a4db94011d3 134
sahilmgandhi 18:6a4db94011d3 135 static int i2c_wait_TEND(i2c_t *obj) {
sahilmgandhi 18:6a4db94011d3 136 int timeout = 0;
sahilmgandhi 18:6a4db94011d3 137
sahilmgandhi 18:6a4db94011d3 138 /* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
sahilmgandhi 18:6a4db94011d3 139 while ((i2c_status(obj) & SR2_TEND) == 0) {
sahilmgandhi 18:6a4db94011d3 140 timeout ++;
sahilmgandhi 18:6a4db94011d3 141 if (timeout >= WAIT_TIMEOUT) {
sahilmgandhi 18:6a4db94011d3 142 return -1;
sahilmgandhi 18:6a4db94011d3 143 }
sahilmgandhi 18:6a4db94011d3 144 }
sahilmgandhi 18:6a4db94011d3 145
sahilmgandhi 18:6a4db94011d3 146 return 0;
sahilmgandhi 18:6a4db94011d3 147 }
sahilmgandhi 18:6a4db94011d3 148
sahilmgandhi 18:6a4db94011d3 149
sahilmgandhi 18:6a4db94011d3 150 static int i2c_wait_START(i2c_t *obj) {
sahilmgandhi 18:6a4db94011d3 151 int timeout = 0;
sahilmgandhi 18:6a4db94011d3 152
sahilmgandhi 18:6a4db94011d3 153 /* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
sahilmgandhi 18:6a4db94011d3 154 while ((i2c_status(obj) & SR2_START) == 0) {
sahilmgandhi 18:6a4db94011d3 155 timeout ++;
sahilmgandhi 18:6a4db94011d3 156 if (timeout >= WAIT_TIMEOUT) {
sahilmgandhi 18:6a4db94011d3 157 return -1;
sahilmgandhi 18:6a4db94011d3 158 }
sahilmgandhi 18:6a4db94011d3 159 }
sahilmgandhi 18:6a4db94011d3 160
sahilmgandhi 18:6a4db94011d3 161 return 0;
sahilmgandhi 18:6a4db94011d3 162 }
sahilmgandhi 18:6a4db94011d3 163
sahilmgandhi 18:6a4db94011d3 164 static int i2c_wait_STOP(i2c_t *obj) {
sahilmgandhi 18:6a4db94011d3 165 int timeout = 0;
sahilmgandhi 18:6a4db94011d3 166
sahilmgandhi 18:6a4db94011d3 167 /* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
sahilmgandhi 18:6a4db94011d3 168 while ((i2c_status(obj) & SR2_STOP) == 0) {
sahilmgandhi 18:6a4db94011d3 169 timeout ++;
sahilmgandhi 18:6a4db94011d3 170 if (timeout >= WAIT_TIMEOUT) {
sahilmgandhi 18:6a4db94011d3 171 return -1;
sahilmgandhi 18:6a4db94011d3 172 }
sahilmgandhi 18:6a4db94011d3 173 }
sahilmgandhi 18:6a4db94011d3 174
sahilmgandhi 18:6a4db94011d3 175 return 0;
sahilmgandhi 18:6a4db94011d3 176 }
sahilmgandhi 18:6a4db94011d3 177
sahilmgandhi 18:6a4db94011d3 178 static int i2c_set_STOP(i2c_t *obj) {
sahilmgandhi 18:6a4db94011d3 179 /* SR2.STOP = 0 */
sahilmgandhi 18:6a4db94011d3 180 REG(SR2.UINT32) &= ~SR2_STOP;
sahilmgandhi 18:6a4db94011d3 181 /* Stop condition */
sahilmgandhi 18:6a4db94011d3 182 REG(CR2.UINT32) |= CR2_SP;
sahilmgandhi 18:6a4db94011d3 183
sahilmgandhi 18:6a4db94011d3 184 return 0;
sahilmgandhi 18:6a4db94011d3 185 }
sahilmgandhi 18:6a4db94011d3 186
sahilmgandhi 18:6a4db94011d3 187 static void i2c_set_SR2_NACKF_STOP(i2c_t *obj) {
sahilmgandhi 18:6a4db94011d3 188 /* SR2.NACKF = 0 */
sahilmgandhi 18:6a4db94011d3 189 REG(SR2.UINT32) &= ~SR2_NACKF;
sahilmgandhi 18:6a4db94011d3 190 /* SR2.STOP = 0 */
sahilmgandhi 18:6a4db94011d3 191 REG(SR2.UINT32) &= ~SR2_STOP;
sahilmgandhi 18:6a4db94011d3 192 }
sahilmgandhi 18:6a4db94011d3 193
sahilmgandhi 18:6a4db94011d3 194 static void i2c_set_MR3_NACK(i2c_t *obj) {
sahilmgandhi 18:6a4db94011d3 195 /* send a NOT ACK */
sahilmgandhi 18:6a4db94011d3 196 REG(MR3.UINT32) |= MR3_ACKWP;
sahilmgandhi 18:6a4db94011d3 197 REG(MR3.UINT32) |= MR3_ACKBT;
sahilmgandhi 18:6a4db94011d3 198 REG(MR3.UINT32) &= ~MR3_ACKWP;
sahilmgandhi 18:6a4db94011d3 199 }
sahilmgandhi 18:6a4db94011d3 200
sahilmgandhi 18:6a4db94011d3 201 static void i2c_set_MR3_ACK(i2c_t *obj) {
sahilmgandhi 18:6a4db94011d3 202 /* send a ACK */
sahilmgandhi 18:6a4db94011d3 203 REG(MR3.UINT32) |= MR3_ACKWP;
sahilmgandhi 18:6a4db94011d3 204 REG(MR3.UINT32) &= ~MR3_ACKBT;
sahilmgandhi 18:6a4db94011d3 205 REG(MR3.UINT32) &= ~MR3_ACKWP;
sahilmgandhi 18:6a4db94011d3 206 }
sahilmgandhi 18:6a4db94011d3 207
sahilmgandhi 18:6a4db94011d3 208 static inline void i2c_power_enable(i2c_t *obj) {
sahilmgandhi 18:6a4db94011d3 209 volatile uint8_t dummy;
sahilmgandhi 18:6a4db94011d3 210 switch ((int)obj->i2c) {
sahilmgandhi 18:6a4db94011d3 211 case I2C_0:
sahilmgandhi 18:6a4db94011d3 212 CPGSTBCR9 &= ~(0x80);
sahilmgandhi 18:6a4db94011d3 213 break;
sahilmgandhi 18:6a4db94011d3 214 case I2C_1:
sahilmgandhi 18:6a4db94011d3 215 CPGSTBCR9 &= ~(0x40);
sahilmgandhi 18:6a4db94011d3 216 break;
sahilmgandhi 18:6a4db94011d3 217 case I2C_2:
sahilmgandhi 18:6a4db94011d3 218 CPGSTBCR9 &= ~(0x20);
sahilmgandhi 18:6a4db94011d3 219 break;
sahilmgandhi 18:6a4db94011d3 220 case I2C_3:
sahilmgandhi 18:6a4db94011d3 221 CPGSTBCR9 &= ~(0x10);
sahilmgandhi 18:6a4db94011d3 222 break;
sahilmgandhi 18:6a4db94011d3 223 }
sahilmgandhi 18:6a4db94011d3 224 dummy = CPGSTBCR9;
sahilmgandhi 18:6a4db94011d3 225 }
sahilmgandhi 18:6a4db94011d3 226
sahilmgandhi 18:6a4db94011d3 227 void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
sahilmgandhi 18:6a4db94011d3 228 /* determine the I2C to use */
sahilmgandhi 18:6a4db94011d3 229 I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
sahilmgandhi 18:6a4db94011d3 230 I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
sahilmgandhi 18:6a4db94011d3 231 obj->i2c = pinmap_merge(i2c_sda, i2c_scl);
sahilmgandhi 18:6a4db94011d3 232 MBED_ASSERT((int)obj->i2c != NC);
sahilmgandhi 18:6a4db94011d3 233
sahilmgandhi 18:6a4db94011d3 234 /* enable power */
sahilmgandhi 18:6a4db94011d3 235 i2c_power_enable(obj);
sahilmgandhi 18:6a4db94011d3 236
sahilmgandhi 18:6a4db94011d3 237 /* set default frequency at 100k */
sahilmgandhi 18:6a4db94011d3 238 i2c_frequency(obj, 100000);
sahilmgandhi 18:6a4db94011d3 239
sahilmgandhi 18:6a4db94011d3 240 pinmap_pinout(sda, PinMap_I2C_SDA);
sahilmgandhi 18:6a4db94011d3 241 pinmap_pinout(scl, PinMap_I2C_SCL);
sahilmgandhi 18:6a4db94011d3 242
sahilmgandhi 18:6a4db94011d3 243 obj->last_stop_flag = 1;
sahilmgandhi 18:6a4db94011d3 244 }
sahilmgandhi 18:6a4db94011d3 245
sahilmgandhi 18:6a4db94011d3 246 inline int i2c_start(i2c_t *obj) {
sahilmgandhi 18:6a4db94011d3 247 int timeout = 0;
sahilmgandhi 18:6a4db94011d3 248
sahilmgandhi 18:6a4db94011d3 249 while ((REG(CR2.UINT32) & CR2_BBSY) != 0) {
sahilmgandhi 18:6a4db94011d3 250 timeout ++;
sahilmgandhi 18:6a4db94011d3 251 if (timeout >= obj->bbsy_wait_cnt) {
sahilmgandhi 18:6a4db94011d3 252 break;
sahilmgandhi 18:6a4db94011d3 253 }
sahilmgandhi 18:6a4db94011d3 254 }
sahilmgandhi 18:6a4db94011d3 255 /* Start Condition */
sahilmgandhi 18:6a4db94011d3 256 REG(CR2.UINT8[0]) |= CR2_ST;
sahilmgandhi 18:6a4db94011d3 257
sahilmgandhi 18:6a4db94011d3 258 return 0;
sahilmgandhi 18:6a4db94011d3 259 }
sahilmgandhi 18:6a4db94011d3 260
sahilmgandhi 18:6a4db94011d3 261 static inline int i2c_restart(i2c_t *obj) {
sahilmgandhi 18:6a4db94011d3 262 /* SR2.START = 0 */
sahilmgandhi 18:6a4db94011d3 263 REG(SR2.UINT32) &= ~SR2_START;
sahilmgandhi 18:6a4db94011d3 264 /* ReStart condition */
sahilmgandhi 18:6a4db94011d3 265 REG(CR2.UINT32) |= CR2_RS;
sahilmgandhi 18:6a4db94011d3 266
sahilmgandhi 18:6a4db94011d3 267 return 0;
sahilmgandhi 18:6a4db94011d3 268 }
sahilmgandhi 18:6a4db94011d3 269
sahilmgandhi 18:6a4db94011d3 270 inline int i2c_stop(i2c_t *obj) {
sahilmgandhi 18:6a4db94011d3 271 (void)i2c_set_STOP(obj);
sahilmgandhi 18:6a4db94011d3 272 (void)i2c_wait_STOP(obj);
sahilmgandhi 18:6a4db94011d3 273 i2c_set_SR2_NACKF_STOP(obj);
sahilmgandhi 18:6a4db94011d3 274
sahilmgandhi 18:6a4db94011d3 275 return 0;
sahilmgandhi 18:6a4db94011d3 276 }
sahilmgandhi 18:6a4db94011d3 277
sahilmgandhi 18:6a4db94011d3 278 static void i2c_set_err_noslave(i2c_t *obj) {
sahilmgandhi 18:6a4db94011d3 279 (void)i2c_set_STOP(obj);
sahilmgandhi 18:6a4db94011d3 280 (void)i2c_wait_STOP(obj);
sahilmgandhi 18:6a4db94011d3 281 i2c_set_SR2_NACKF_STOP(obj);
sahilmgandhi 18:6a4db94011d3 282 obj->last_stop_flag = 1;
sahilmgandhi 18:6a4db94011d3 283 }
sahilmgandhi 18:6a4db94011d3 284
sahilmgandhi 18:6a4db94011d3 285 static inline int i2c_do_write(i2c_t *obj, int value) {
sahilmgandhi 18:6a4db94011d3 286 int timeout = 0;
sahilmgandhi 18:6a4db94011d3 287
sahilmgandhi 18:6a4db94011d3 288 /* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
sahilmgandhi 18:6a4db94011d3 289 while ((i2c_status(obj) & SR2_TDRE) == 0) {
sahilmgandhi 18:6a4db94011d3 290 timeout ++;
sahilmgandhi 18:6a4db94011d3 291 if (timeout >= WAIT_TIMEOUT) {
sahilmgandhi 18:6a4db94011d3 292 return -1;
sahilmgandhi 18:6a4db94011d3 293 }
sahilmgandhi 18:6a4db94011d3 294 }
sahilmgandhi 18:6a4db94011d3 295 /* write the data */
sahilmgandhi 18:6a4db94011d3 296 REG(DRT.UINT32) = value;
sahilmgandhi 18:6a4db94011d3 297
sahilmgandhi 18:6a4db94011d3 298 return 0;
sahilmgandhi 18:6a4db94011d3 299 }
sahilmgandhi 18:6a4db94011d3 300
sahilmgandhi 18:6a4db94011d3 301 static inline int i2c_read_address_write(i2c_t *obj, int value) {
sahilmgandhi 18:6a4db94011d3 302 int status;
sahilmgandhi 18:6a4db94011d3 303
sahilmgandhi 18:6a4db94011d3 304 status = i2c_wait_TDRE(obj);
sahilmgandhi 18:6a4db94011d3 305 if (status == 0) {
sahilmgandhi 18:6a4db94011d3 306 /* write the data */
sahilmgandhi 18:6a4db94011d3 307 REG(DRT.UINT32) = value;
sahilmgandhi 18:6a4db94011d3 308 }
sahilmgandhi 18:6a4db94011d3 309
sahilmgandhi 18:6a4db94011d3 310 return status;
sahilmgandhi 18:6a4db94011d3 311
sahilmgandhi 18:6a4db94011d3 312 }
sahilmgandhi 18:6a4db94011d3 313
sahilmgandhi 18:6a4db94011d3 314 static inline int i2c_do_read(i2c_t *obj, int last) {
sahilmgandhi 18:6a4db94011d3 315 if (last == 2) {
sahilmgandhi 18:6a4db94011d3 316 /* this time is befor last byte read */
sahilmgandhi 18:6a4db94011d3 317 /* Set MR3 WAIT bit is 1 */;
sahilmgandhi 18:6a4db94011d3 318 REG(MR3.UINT32) |= MR3_WAIT;
sahilmgandhi 18:6a4db94011d3 319 } else if (last == 1) {
sahilmgandhi 18:6a4db94011d3 320 i2c_set_MR3_NACK(obj);
sahilmgandhi 18:6a4db94011d3 321 } else {
sahilmgandhi 18:6a4db94011d3 322 i2c_set_MR3_ACK(obj);
sahilmgandhi 18:6a4db94011d3 323 }
sahilmgandhi 18:6a4db94011d3 324
sahilmgandhi 18:6a4db94011d3 325 /* return the data */
sahilmgandhi 18:6a4db94011d3 326 return (REG(DRR.UINT32) & 0xFF);
sahilmgandhi 18:6a4db94011d3 327 }
sahilmgandhi 18:6a4db94011d3 328
sahilmgandhi 18:6a4db94011d3 329 void i2c_frequency(i2c_t *obj, int hz) {
sahilmgandhi 18:6a4db94011d3 330 float64_t pclk_val;
sahilmgandhi 18:6a4db94011d3 331 float64_t wait_utime;
sahilmgandhi 18:6a4db94011d3 332 volatile float64_t bps;
sahilmgandhi 18:6a4db94011d3 333 volatile float64_t L_time; /* H Width period */
sahilmgandhi 18:6a4db94011d3 334 volatile float64_t H_time; /* L Width period */
sahilmgandhi 18:6a4db94011d3 335 uint32_t tmp_L_width;
sahilmgandhi 18:6a4db94011d3 336 uint32_t tmp_H_width;
sahilmgandhi 18:6a4db94011d3 337 uint32_t remainder;
sahilmgandhi 18:6a4db94011d3 338 uint32_t wk_cks = 0;
sahilmgandhi 18:6a4db94011d3 339
sahilmgandhi 18:6a4db94011d3 340 /* set PCLK */
sahilmgandhi 18:6a4db94011d3 341 if (false == RZ_A1_IsClockMode0()) {
sahilmgandhi 18:6a4db94011d3 342 pclk_val = (float64_t)CM1_RENESAS_RZ_A1_P0_CLK;
sahilmgandhi 18:6a4db94011d3 343 } else {
sahilmgandhi 18:6a4db94011d3 344 pclk_val = (float64_t)CM0_RENESAS_RZ_A1_P0_CLK;
sahilmgandhi 18:6a4db94011d3 345 }
sahilmgandhi 18:6a4db94011d3 346
sahilmgandhi 18:6a4db94011d3 347 /* Min 10kHz, Max 400kHz */
sahilmgandhi 18:6a4db94011d3 348 if (hz < 10000) {
sahilmgandhi 18:6a4db94011d3 349 bps = 10000;
sahilmgandhi 18:6a4db94011d3 350 } else if (hz > 400000) {
sahilmgandhi 18:6a4db94011d3 351 bps = 400000;
sahilmgandhi 18:6a4db94011d3 352 } else {
sahilmgandhi 18:6a4db94011d3 353 bps = (float64_t)hz;
sahilmgandhi 18:6a4db94011d3 354 }
sahilmgandhi 18:6a4db94011d3 355
sahilmgandhi 18:6a4db94011d3 356 /* Calculation L width time */
sahilmgandhi 18:6a4db94011d3 357 L_time = (1 / (2 * bps)); /* Harf period of frequency */
sahilmgandhi 18:6a4db94011d3 358 H_time = L_time;
sahilmgandhi 18:6a4db94011d3 359
sahilmgandhi 18:6a4db94011d3 360 /* Check I2C mode of Speed */
sahilmgandhi 18:6a4db94011d3 361 if (bps > 100000) {
sahilmgandhi 18:6a4db94011d3 362 /* Fast-mode */
sahilmgandhi 18:6a4db94011d3 363 L_time -= 102E-9; /* Falling time of SCL clock. */
sahilmgandhi 18:6a4db94011d3 364 H_time -= 138E-9; /* Rising time of SCL clock. */
sahilmgandhi 18:6a4db94011d3 365 /* Check L wideth */
sahilmgandhi 18:6a4db94011d3 366 if (L_time < 1.3E-6) {
sahilmgandhi 18:6a4db94011d3 367 /* Wnen L width less than 1.3us */
sahilmgandhi 18:6a4db94011d3 368 /* Subtract Rise up and down time for SCL from H/L width */
sahilmgandhi 18:6a4db94011d3 369 L_time = 1.3E-6;
sahilmgandhi 18:6a4db94011d3 370 H_time = (1 / bps) - L_time - 138E-9 - 102E-9;
sahilmgandhi 18:6a4db94011d3 371 }
sahilmgandhi 18:6a4db94011d3 372 }
sahilmgandhi 18:6a4db94011d3 373
sahilmgandhi 18:6a4db94011d3 374 tmp_L_width = (uint32_t)(L_time * pclk_val * 10);
sahilmgandhi 18:6a4db94011d3 375 tmp_L_width >>= 1;
sahilmgandhi 18:6a4db94011d3 376 wk_cks++;
sahilmgandhi 18:6a4db94011d3 377 while (tmp_L_width >= 341) {
sahilmgandhi 18:6a4db94011d3 378 tmp_L_width >>= 1;
sahilmgandhi 18:6a4db94011d3 379 wk_cks++;
sahilmgandhi 18:6a4db94011d3 380 }
sahilmgandhi 18:6a4db94011d3 381 remainder = tmp_L_width % 10;
sahilmgandhi 18:6a4db94011d3 382 tmp_L_width = ((tmp_L_width + 9) / 10) - 3; /* carry */
sahilmgandhi 18:6a4db94011d3 383
sahilmgandhi 18:6a4db94011d3 384 tmp_H_width = (uint32_t)(H_time * pclk_val * 10);
sahilmgandhi 18:6a4db94011d3 385 tmp_H_width >>= wk_cks;
sahilmgandhi 18:6a4db94011d3 386 if (remainder == 0) {
sahilmgandhi 18:6a4db94011d3 387 tmp_H_width = ((tmp_H_width + 9) / 10) - 3; /* carry */
sahilmgandhi 18:6a4db94011d3 388 } else {
sahilmgandhi 18:6a4db94011d3 389 remainder += tmp_H_width % 10;
sahilmgandhi 18:6a4db94011d3 390 tmp_H_width = (tmp_H_width / 10) - 3;
sahilmgandhi 18:6a4db94011d3 391 if (remainder > 10) {
sahilmgandhi 18:6a4db94011d3 392 tmp_H_width += 1; /* fine adjustment */
sahilmgandhi 18:6a4db94011d3 393 }
sahilmgandhi 18:6a4db94011d3 394 }
sahilmgandhi 18:6a4db94011d3 395 /* timeout of BBSY bit is minimum low width by frequency */
sahilmgandhi 18:6a4db94011d3 396 /* so timeout calculates "(low width) * 2" by frequency */
sahilmgandhi 18:6a4db94011d3 397 wait_utime = (L_time * 2) * 1000000;
sahilmgandhi 18:6a4db94011d3 398 /* 1 wait of BBSY bit is about 0.3us. if it's below 0.3us, wait count is set as 1. */
sahilmgandhi 18:6a4db94011d3 399 if (wait_utime <= 0.3) {
sahilmgandhi 18:6a4db94011d3 400 obj->bbsy_wait_cnt = 1;
sahilmgandhi 18:6a4db94011d3 401 } else {
sahilmgandhi 18:6a4db94011d3 402 obj->bbsy_wait_cnt = (int)(wait_utime / 0.3);
sahilmgandhi 18:6a4db94011d3 403 }
sahilmgandhi 18:6a4db94011d3 404
sahilmgandhi 18:6a4db94011d3 405
sahilmgandhi 18:6a4db94011d3 406 /* I2C Rate */
sahilmgandhi 18:6a4db94011d3 407 obj->pclk_bit = (uint8_t)(0x10 * wk_cks); /* P_phi / xx */
sahilmgandhi 18:6a4db94011d3 408 obj->width_low = (uint8_t)(tmp_L_width | 0x000000E0);
sahilmgandhi 18:6a4db94011d3 409 obj->width_hi = (uint8_t)(tmp_H_width | 0x000000E0);
sahilmgandhi 18:6a4db94011d3 410
sahilmgandhi 18:6a4db94011d3 411 /* full reset */
sahilmgandhi 18:6a4db94011d3 412 i2c_reg_reset(obj);
sahilmgandhi 18:6a4db94011d3 413 }
sahilmgandhi 18:6a4db94011d3 414
sahilmgandhi 18:6a4db94011d3 415 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
sahilmgandhi 18:6a4db94011d3 416 int count = 0;
sahilmgandhi 18:6a4db94011d3 417 int status;
sahilmgandhi 18:6a4db94011d3 418 int value;
sahilmgandhi 18:6a4db94011d3 419 volatile uint32_t work_reg = 0;
sahilmgandhi 18:6a4db94011d3 420
sahilmgandhi 18:6a4db94011d3 421 i2c_set_MR3_ACK(obj);
sahilmgandhi 18:6a4db94011d3 422 /* There is a STOP condition for last processing */
sahilmgandhi 18:6a4db94011d3 423 if (obj->last_stop_flag != 0) {
sahilmgandhi 18:6a4db94011d3 424 status = i2c_start(obj);
sahilmgandhi 18:6a4db94011d3 425 if (status != 0) {
sahilmgandhi 18:6a4db94011d3 426 i2c_set_err_noslave(obj);
sahilmgandhi 18:6a4db94011d3 427 return I2C_ERROR_BUS_BUSY;
sahilmgandhi 18:6a4db94011d3 428 }
sahilmgandhi 18:6a4db94011d3 429 }
sahilmgandhi 18:6a4db94011d3 430 obj->last_stop_flag = stop;
sahilmgandhi 18:6a4db94011d3 431 /* Send Slave address */
sahilmgandhi 18:6a4db94011d3 432 status = i2c_read_address_write(obj, (address | 0x01));
sahilmgandhi 18:6a4db94011d3 433 if (status != 0) {
sahilmgandhi 18:6a4db94011d3 434 i2c_set_err_noslave(obj);
sahilmgandhi 18:6a4db94011d3 435 return I2C_ERROR_NO_SLAVE;
sahilmgandhi 18:6a4db94011d3 436 }
sahilmgandhi 18:6a4db94011d3 437 /* wait RDRF */
sahilmgandhi 18:6a4db94011d3 438 status = i2c_wait_RDRF(obj);
sahilmgandhi 18:6a4db94011d3 439 /* check ACK/NACK */
sahilmgandhi 18:6a4db94011d3 440 if ((status != 0) || ((REG(SR2.UINT32) & SR2_NACKF) != 0)) {
sahilmgandhi 18:6a4db94011d3 441 /* Slave sends NACK */
sahilmgandhi 18:6a4db94011d3 442 (void)i2c_set_STOP(obj);
sahilmgandhi 18:6a4db94011d3 443 /* dummy read */
sahilmgandhi 18:6a4db94011d3 444 value = REG(DRR.UINT32);
sahilmgandhi 18:6a4db94011d3 445 (void)i2c_wait_STOP(obj);
sahilmgandhi 18:6a4db94011d3 446 i2c_set_SR2_NACKF_STOP(obj);
sahilmgandhi 18:6a4db94011d3 447 obj->last_stop_flag = 1;
sahilmgandhi 18:6a4db94011d3 448 return I2C_ERROR_NO_SLAVE;
sahilmgandhi 18:6a4db94011d3 449 }
sahilmgandhi 18:6a4db94011d3 450 if (length != 0) {
sahilmgandhi 18:6a4db94011d3 451 /* Read in all except last byte */
sahilmgandhi 18:6a4db94011d3 452 if (length > 2) {
sahilmgandhi 18:6a4db94011d3 453 /* dummy read */
sahilmgandhi 18:6a4db94011d3 454 value = REG(DRR.UINT32);
sahilmgandhi 18:6a4db94011d3 455 for (count = 0; count < (length - 1); count++) {
sahilmgandhi 18:6a4db94011d3 456 /* wait for it to arrive */
sahilmgandhi 18:6a4db94011d3 457 status = i2c_wait_RDRF(obj);
sahilmgandhi 18:6a4db94011d3 458 if (status != 0) {
sahilmgandhi 18:6a4db94011d3 459 i2c_set_err_noslave(obj);
sahilmgandhi 18:6a4db94011d3 460 return I2C_ERROR_NO_SLAVE;
sahilmgandhi 18:6a4db94011d3 461 }
sahilmgandhi 18:6a4db94011d3 462 /* Recieve the data */
sahilmgandhi 18:6a4db94011d3 463 if (count == (length - 2)) {
sahilmgandhi 18:6a4db94011d3 464 value = i2c_do_read(obj, 1);
sahilmgandhi 18:6a4db94011d3 465 } else if ((length >= 3) && (count == (length - 3))) {
sahilmgandhi 18:6a4db94011d3 466 value = i2c_do_read(obj, 2);
sahilmgandhi 18:6a4db94011d3 467 } else {
sahilmgandhi 18:6a4db94011d3 468 value = i2c_do_read(obj, 0);
sahilmgandhi 18:6a4db94011d3 469 }
sahilmgandhi 18:6a4db94011d3 470 data[count] = (char)value;
sahilmgandhi 18:6a4db94011d3 471 }
sahilmgandhi 18:6a4db94011d3 472 } else if (length == 2) {
sahilmgandhi 18:6a4db94011d3 473 /* Set MR3 WAIT bit is 1 */
sahilmgandhi 18:6a4db94011d3 474 REG(MR3.UINT32) |= MR3_WAIT;
sahilmgandhi 18:6a4db94011d3 475 /* dummy read */
sahilmgandhi 18:6a4db94011d3 476 value = REG(DRR.UINT32);
sahilmgandhi 18:6a4db94011d3 477 /* wait for it to arrive */
sahilmgandhi 18:6a4db94011d3 478 status = i2c_wait_RDRF(obj);
sahilmgandhi 18:6a4db94011d3 479 if (status != 0) {
sahilmgandhi 18:6a4db94011d3 480 i2c_set_err_noslave(obj);
sahilmgandhi 18:6a4db94011d3 481 return I2C_ERROR_NO_SLAVE;
sahilmgandhi 18:6a4db94011d3 482 }
sahilmgandhi 18:6a4db94011d3 483 i2c_set_MR3_NACK(obj);
sahilmgandhi 18:6a4db94011d3 484 data[count] = (char)REG(DRR.UINT32);
sahilmgandhi 18:6a4db94011d3 485 count++;
sahilmgandhi 18:6a4db94011d3 486 } else {
sahilmgandhi 18:6a4db94011d3 487 /* length == 1 */
sahilmgandhi 18:6a4db94011d3 488 /* Set MR3 WAIT bit is 1 */;
sahilmgandhi 18:6a4db94011d3 489 REG(MR3.UINT32) |= MR3_WAIT;
sahilmgandhi 18:6a4db94011d3 490 i2c_set_MR3_NACK(obj);
sahilmgandhi 18:6a4db94011d3 491 /* dummy read */
sahilmgandhi 18:6a4db94011d3 492 value = REG(DRR.UINT32);
sahilmgandhi 18:6a4db94011d3 493 }
sahilmgandhi 18:6a4db94011d3 494 /* wait for it to arrive */
sahilmgandhi 18:6a4db94011d3 495 status = i2c_wait_RDRF(obj);
sahilmgandhi 18:6a4db94011d3 496 if (status != 0) {
sahilmgandhi 18:6a4db94011d3 497 i2c_set_err_noslave(obj);
sahilmgandhi 18:6a4db94011d3 498 return I2C_ERROR_NO_SLAVE;
sahilmgandhi 18:6a4db94011d3 499 }
sahilmgandhi 18:6a4db94011d3 500
sahilmgandhi 18:6a4db94011d3 501 /* If not repeated start, send stop. */
sahilmgandhi 18:6a4db94011d3 502 if (stop) {
sahilmgandhi 18:6a4db94011d3 503 (void)i2c_set_STOP(obj);
sahilmgandhi 18:6a4db94011d3 504 /* RIICnDRR read */
sahilmgandhi 18:6a4db94011d3 505 value = (REG(DRR.UINT32) & 0xFF);
sahilmgandhi 18:6a4db94011d3 506 data[count] = (char)value;
sahilmgandhi 18:6a4db94011d3 507 /* RIICnMR3.WAIT = 0 */
sahilmgandhi 18:6a4db94011d3 508 REG(MR3.UINT32) &= ~MR3_WAIT;
sahilmgandhi 18:6a4db94011d3 509 (void)i2c_wait_STOP(obj);
sahilmgandhi 18:6a4db94011d3 510 i2c_set_SR2_NACKF_STOP(obj);
sahilmgandhi 18:6a4db94011d3 511 } else {
sahilmgandhi 18:6a4db94011d3 512 (void)i2c_restart(obj);
sahilmgandhi 18:6a4db94011d3 513 /* RIICnDRR read */
sahilmgandhi 18:6a4db94011d3 514 value = (REG(DRR.UINT32) & 0xFF);
sahilmgandhi 18:6a4db94011d3 515 data[count] = (char)value;
sahilmgandhi 18:6a4db94011d3 516 /* RIICnMR3.WAIT = 0 */
sahilmgandhi 18:6a4db94011d3 517 REG(MR3.UINT32) &= ~MR3_WAIT;
sahilmgandhi 18:6a4db94011d3 518 (void)i2c_wait_START(obj);
sahilmgandhi 18:6a4db94011d3 519 /* SR2.START = 0 */
sahilmgandhi 18:6a4db94011d3 520 REG(SR2.UINT32) &= ~SR2_START;
sahilmgandhi 18:6a4db94011d3 521 }
sahilmgandhi 18:6a4db94011d3 522 } else {
sahilmgandhi 18:6a4db94011d3 523 /* If not repeated start, send stop. */
sahilmgandhi 18:6a4db94011d3 524 if (stop) {
sahilmgandhi 18:6a4db94011d3 525 (void)i2c_set_STOP(obj);
sahilmgandhi 18:6a4db94011d3 526 (void)i2c_wait_STOP(obj);
sahilmgandhi 18:6a4db94011d3 527 i2c_set_SR2_NACKF_STOP(obj);
sahilmgandhi 18:6a4db94011d3 528 } else {
sahilmgandhi 18:6a4db94011d3 529 (void)i2c_restart(obj);
sahilmgandhi 18:6a4db94011d3 530 (void)i2c_wait_START(obj);
sahilmgandhi 18:6a4db94011d3 531 /* SR2.START = 0 */
sahilmgandhi 18:6a4db94011d3 532 REG(SR2.UINT32) &= ~SR2_START;
sahilmgandhi 18:6a4db94011d3 533 }
sahilmgandhi 18:6a4db94011d3 534 }
sahilmgandhi 18:6a4db94011d3 535
sahilmgandhi 18:6a4db94011d3 536 return length;
sahilmgandhi 18:6a4db94011d3 537 }
sahilmgandhi 18:6a4db94011d3 538
sahilmgandhi 18:6a4db94011d3 539 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
sahilmgandhi 18:6a4db94011d3 540 int cnt;
sahilmgandhi 18:6a4db94011d3 541 int status;
sahilmgandhi 18:6a4db94011d3 542
sahilmgandhi 18:6a4db94011d3 543 /* There is a STOP condition for last processing */
sahilmgandhi 18:6a4db94011d3 544 if (obj->last_stop_flag != 0) {
sahilmgandhi 18:6a4db94011d3 545 status = i2c_start(obj);
sahilmgandhi 18:6a4db94011d3 546 if (status != 0) {
sahilmgandhi 18:6a4db94011d3 547 i2c_set_err_noslave(obj);
sahilmgandhi 18:6a4db94011d3 548 return I2C_ERROR_BUS_BUSY;
sahilmgandhi 18:6a4db94011d3 549 }
sahilmgandhi 18:6a4db94011d3 550 }
sahilmgandhi 18:6a4db94011d3 551 obj->last_stop_flag = stop;
sahilmgandhi 18:6a4db94011d3 552 /* Send Slave address */
sahilmgandhi 18:6a4db94011d3 553 status = i2c_do_write(obj, address);
sahilmgandhi 18:6a4db94011d3 554 if (status != 0) {
sahilmgandhi 18:6a4db94011d3 555 i2c_set_err_noslave(obj);
sahilmgandhi 18:6a4db94011d3 556 return I2C_ERROR_NO_SLAVE;
sahilmgandhi 18:6a4db94011d3 557 }
sahilmgandhi 18:6a4db94011d3 558 /* Wait send end */
sahilmgandhi 18:6a4db94011d3 559 status = i2c_wait_TEND(obj);
sahilmgandhi 18:6a4db94011d3 560 if ((status != 0) || ((REG(SR2.UINT32) & SR2_NACKF) != 0)) {
sahilmgandhi 18:6a4db94011d3 561 /* Slave sends NACK */
sahilmgandhi 18:6a4db94011d3 562 i2c_set_err_noslave(obj);
sahilmgandhi 18:6a4db94011d3 563 return I2C_ERROR_NO_SLAVE;
sahilmgandhi 18:6a4db94011d3 564 }
sahilmgandhi 18:6a4db94011d3 565 /* Send Write data */
sahilmgandhi 18:6a4db94011d3 566 for (cnt=0; cnt<length; cnt++) {
sahilmgandhi 18:6a4db94011d3 567 status = i2c_do_write(obj, data[cnt]);
sahilmgandhi 18:6a4db94011d3 568 if(status != 0) {
sahilmgandhi 18:6a4db94011d3 569 i2c_set_err_noslave(obj);
sahilmgandhi 18:6a4db94011d3 570 return cnt;
sahilmgandhi 18:6a4db94011d3 571 } else {
sahilmgandhi 18:6a4db94011d3 572 /* Wait send end */
sahilmgandhi 18:6a4db94011d3 573 status = i2c_wait_TEND(obj);
sahilmgandhi 18:6a4db94011d3 574 if ((status != 0) || ((REG(SR2.UINT32) & SR2_NACKF) != 0)) {
sahilmgandhi 18:6a4db94011d3 575 /* Slave sends NACK */
sahilmgandhi 18:6a4db94011d3 576 i2c_set_err_noslave(obj);
sahilmgandhi 18:6a4db94011d3 577 return I2C_ERROR_NO_SLAVE;
sahilmgandhi 18:6a4db94011d3 578 }
sahilmgandhi 18:6a4db94011d3 579 }
sahilmgandhi 18:6a4db94011d3 580 }
sahilmgandhi 18:6a4db94011d3 581 /* If not repeated start, send stop. */
sahilmgandhi 18:6a4db94011d3 582 if (stop) {
sahilmgandhi 18:6a4db94011d3 583 (void)i2c_set_STOP(obj);
sahilmgandhi 18:6a4db94011d3 584 (void)i2c_wait_STOP(obj);
sahilmgandhi 18:6a4db94011d3 585 i2c_set_SR2_NACKF_STOP(obj);
sahilmgandhi 18:6a4db94011d3 586 } else {
sahilmgandhi 18:6a4db94011d3 587 (void)i2c_restart(obj);
sahilmgandhi 18:6a4db94011d3 588 (void)i2c_wait_START(obj);
sahilmgandhi 18:6a4db94011d3 589 /* SR2.START = 0 */
sahilmgandhi 18:6a4db94011d3 590 REG(SR2.UINT32) &= ~SR2_START;
sahilmgandhi 18:6a4db94011d3 591
sahilmgandhi 18:6a4db94011d3 592 }
sahilmgandhi 18:6a4db94011d3 593
sahilmgandhi 18:6a4db94011d3 594 return length;
sahilmgandhi 18:6a4db94011d3 595 }
sahilmgandhi 18:6a4db94011d3 596
sahilmgandhi 18:6a4db94011d3 597 void i2c_reset(i2c_t *obj) {
sahilmgandhi 18:6a4db94011d3 598 (void)i2c_set_STOP(obj);
sahilmgandhi 18:6a4db94011d3 599 (void)i2c_wait_STOP(obj);
sahilmgandhi 18:6a4db94011d3 600 i2c_set_SR2_NACKF_STOP(obj);
sahilmgandhi 18:6a4db94011d3 601 }
sahilmgandhi 18:6a4db94011d3 602
sahilmgandhi 18:6a4db94011d3 603 int i2c_byte_read(i2c_t *obj, int last) {
sahilmgandhi 18:6a4db94011d3 604 int status;
sahilmgandhi 18:6a4db94011d3 605 int data;
sahilmgandhi 18:6a4db94011d3 606
sahilmgandhi 18:6a4db94011d3 607 data = i2c_do_read(obj, last);
sahilmgandhi 18:6a4db94011d3 608 /* wait for it to arrive */
sahilmgandhi 18:6a4db94011d3 609 status = i2c_wait_RDRF(obj);
sahilmgandhi 18:6a4db94011d3 610 if (status != 0) {
sahilmgandhi 18:6a4db94011d3 611 i2c_set_SR2_NACKF_STOP(obj);
sahilmgandhi 18:6a4db94011d3 612 return I2C_ERROR_NO_SLAVE;
sahilmgandhi 18:6a4db94011d3 613 }
sahilmgandhi 18:6a4db94011d3 614
sahilmgandhi 18:6a4db94011d3 615 return data;
sahilmgandhi 18:6a4db94011d3 616 }
sahilmgandhi 18:6a4db94011d3 617
sahilmgandhi 18:6a4db94011d3 618 int i2c_byte_write(i2c_t *obj, int data) {
sahilmgandhi 18:6a4db94011d3 619 int ack = 0;
sahilmgandhi 18:6a4db94011d3 620 int status;
sahilmgandhi 18:6a4db94011d3 621 int timeout = 0;
sahilmgandhi 18:6a4db94011d3 622
sahilmgandhi 18:6a4db94011d3 623 status = i2c_do_write(obj, (data & 0xFF));
sahilmgandhi 18:6a4db94011d3 624 if (status != 0) {
sahilmgandhi 18:6a4db94011d3 625 i2c_set_SR2_NACKF_STOP(obj);
sahilmgandhi 18:6a4db94011d3 626 } else {
sahilmgandhi 18:6a4db94011d3 627 while (((i2c_status(obj) & SR2_RDRF) == 0) && ((i2c_status(obj) & SR2_TEND) == 0)) {
sahilmgandhi 18:6a4db94011d3 628 timeout++;
sahilmgandhi 18:6a4db94011d3 629 if (timeout >= WAIT_TIMEOUT) {
sahilmgandhi 18:6a4db94011d3 630 return ack;
sahilmgandhi 18:6a4db94011d3 631 }
sahilmgandhi 18:6a4db94011d3 632 }
sahilmgandhi 18:6a4db94011d3 633 /* check ACK/NACK */
sahilmgandhi 18:6a4db94011d3 634 if ((REG(SR2.UINT32) & SR2_NACKF) != 0) {
sahilmgandhi 18:6a4db94011d3 635 /* NACK */
sahilmgandhi 18:6a4db94011d3 636 i2c_set_SR2_NACKF_STOP(obj);
sahilmgandhi 18:6a4db94011d3 637 } else {
sahilmgandhi 18:6a4db94011d3 638 ack = 1;
sahilmgandhi 18:6a4db94011d3 639 }
sahilmgandhi 18:6a4db94011d3 640 }
sahilmgandhi 18:6a4db94011d3 641
sahilmgandhi 18:6a4db94011d3 642 return ack;
sahilmgandhi 18:6a4db94011d3 643 }
sahilmgandhi 18:6a4db94011d3 644
sahilmgandhi 18:6a4db94011d3 645 void i2c_slave_mode(i2c_t *obj, int enable_slave) {
sahilmgandhi 18:6a4db94011d3 646 if (enable_slave != 0) {
sahilmgandhi 18:6a4db94011d3 647 REG(SER.UINT32) |= SER_SAR0E; // only slave addr 0 is enabled
sahilmgandhi 18:6a4db94011d3 648 } else {
sahilmgandhi 18:6a4db94011d3 649 REG(SER.UINT32) &= ~SER_SAR0E; // no slave addr enabled
sahilmgandhi 18:6a4db94011d3 650 }
sahilmgandhi 18:6a4db94011d3 651 }
sahilmgandhi 18:6a4db94011d3 652
sahilmgandhi 18:6a4db94011d3 653 int i2c_slave_receive(i2c_t *obj) {
sahilmgandhi 18:6a4db94011d3 654 int status;
sahilmgandhi 18:6a4db94011d3 655 int retval;
sahilmgandhi 18:6a4db94011d3 656
sahilmgandhi 18:6a4db94011d3 657 status = (REG(SR1.UINT8[0]) & SR1_AAS0);
sahilmgandhi 18:6a4db94011d3 658 status |= (REG(CR2.UINT8[0]) & CR2_TRS) >> 4;
sahilmgandhi 18:6a4db94011d3 659
sahilmgandhi 18:6a4db94011d3 660 switch(status) {
sahilmgandhi 18:6a4db94011d3 661 case 0x01:
sahilmgandhi 18:6a4db94011d3 662 /* the master is writing to this slave */
sahilmgandhi 18:6a4db94011d3 663 retval = 3;
sahilmgandhi 18:6a4db94011d3 664 break;
sahilmgandhi 18:6a4db94011d3 665 case 0x02:
sahilmgandhi 18:6a4db94011d3 666 /* the master is writing to all slave */
sahilmgandhi 18:6a4db94011d3 667 retval = 2;
sahilmgandhi 18:6a4db94011d3 668 break;
sahilmgandhi 18:6a4db94011d3 669 case 0x03:
sahilmgandhi 18:6a4db94011d3 670 /* the master has requested a read from this slave */
sahilmgandhi 18:6a4db94011d3 671 retval = 1;
sahilmgandhi 18:6a4db94011d3 672 break;
sahilmgandhi 18:6a4db94011d3 673 default :
sahilmgandhi 18:6a4db94011d3 674 /* no data */
sahilmgandhi 18:6a4db94011d3 675 retval = 0;
sahilmgandhi 18:6a4db94011d3 676 break;
sahilmgandhi 18:6a4db94011d3 677 }
sahilmgandhi 18:6a4db94011d3 678
sahilmgandhi 18:6a4db94011d3 679 return retval;
sahilmgandhi 18:6a4db94011d3 680 }
sahilmgandhi 18:6a4db94011d3 681
sahilmgandhi 18:6a4db94011d3 682 int i2c_slave_read(i2c_t *obj, char *data, int length) {
sahilmgandhi 18:6a4db94011d3 683 int timeout = 0;
sahilmgandhi 18:6a4db94011d3 684 int count;
sahilmgandhi 18:6a4db94011d3 685 int break_flg = 0;
sahilmgandhi 18:6a4db94011d3 686
sahilmgandhi 18:6a4db94011d3 687 if(length <= 0) {
sahilmgandhi 18:6a4db94011d3 688 return 0;
sahilmgandhi 18:6a4db94011d3 689 }
sahilmgandhi 18:6a4db94011d3 690 for (count = 0; ((count < (length + 1)) && (break_flg == 0)); count++) {
sahilmgandhi 18:6a4db94011d3 691 /* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
sahilmgandhi 18:6a4db94011d3 692 while (((i2c_status(obj) & SR2_STOP) != 0) || ((i2c_status(obj) & SR2_RDRF) == 0)) {
sahilmgandhi 18:6a4db94011d3 693 if ((i2c_status(obj) & SR2_STOP) != 0) {
sahilmgandhi 18:6a4db94011d3 694 break_flg = 1;
sahilmgandhi 18:6a4db94011d3 695 break;
sahilmgandhi 18:6a4db94011d3 696 }
sahilmgandhi 18:6a4db94011d3 697 timeout ++;
sahilmgandhi 18:6a4db94011d3 698 if (timeout >= WAIT_TIMEOUT) {
sahilmgandhi 18:6a4db94011d3 699 return -1;
sahilmgandhi 18:6a4db94011d3 700 }
sahilmgandhi 18:6a4db94011d3 701 }
sahilmgandhi 18:6a4db94011d3 702 if (break_flg == 0) {
sahilmgandhi 18:6a4db94011d3 703 if (count == 0) {
sahilmgandhi 18:6a4db94011d3 704 /* dummy read */
sahilmgandhi 18:6a4db94011d3 705 (void)REG(DRR.UINT32);
sahilmgandhi 18:6a4db94011d3 706 } else {
sahilmgandhi 18:6a4db94011d3 707 data[count - 1] = (char)(REG(DRR.UINT32) & 0xFF);
sahilmgandhi 18:6a4db94011d3 708 }
sahilmgandhi 18:6a4db94011d3 709 }
sahilmgandhi 18:6a4db94011d3 710 }
sahilmgandhi 18:6a4db94011d3 711 if (break_flg == 0) {
sahilmgandhi 18:6a4db94011d3 712 (void)i2c_wait_STOP(obj);
sahilmgandhi 18:6a4db94011d3 713 } else {
sahilmgandhi 18:6a4db94011d3 714 if ((i2c_status(obj) & SR2_RDRF) != 0) {
sahilmgandhi 18:6a4db94011d3 715 if (count <= 1) {
sahilmgandhi 18:6a4db94011d3 716 /* fail safe */
sahilmgandhi 18:6a4db94011d3 717 /* dummy read */
sahilmgandhi 18:6a4db94011d3 718 (void)REG(DRR.UINT32);
sahilmgandhi 18:6a4db94011d3 719 } else {
sahilmgandhi 18:6a4db94011d3 720 data[count - 2] = (char)(REG(DRR.UINT32) & 0xFF);
sahilmgandhi 18:6a4db94011d3 721 }
sahilmgandhi 18:6a4db94011d3 722 }
sahilmgandhi 18:6a4db94011d3 723 }
sahilmgandhi 18:6a4db94011d3 724 /* SR2.STOP = 0 */
sahilmgandhi 18:6a4db94011d3 725 REG(SR2.UINT32) &= ~SR2_STOP;
sahilmgandhi 18:6a4db94011d3 726
sahilmgandhi 18:6a4db94011d3 727 return (count - 1);
sahilmgandhi 18:6a4db94011d3 728 }
sahilmgandhi 18:6a4db94011d3 729
sahilmgandhi 18:6a4db94011d3 730 int i2c_slave_write(i2c_t *obj, const char *data, int length) {
sahilmgandhi 18:6a4db94011d3 731 int count = 0;
sahilmgandhi 18:6a4db94011d3 732 int status = 0;
sahilmgandhi 18:6a4db94011d3 733
sahilmgandhi 18:6a4db94011d3 734 if(length <= 0) {
sahilmgandhi 18:6a4db94011d3 735 return 0;
sahilmgandhi 18:6a4db94011d3 736 }
sahilmgandhi 18:6a4db94011d3 737
sahilmgandhi 18:6a4db94011d3 738 while ((count < length) && (status == 0)) {
sahilmgandhi 18:6a4db94011d3 739 status = i2c_do_write(obj, data[count]);
sahilmgandhi 18:6a4db94011d3 740 if(status == 0) {
sahilmgandhi 18:6a4db94011d3 741 /* Wait send end */
sahilmgandhi 18:6a4db94011d3 742 status = i2c_wait_TEND(obj);
sahilmgandhi 18:6a4db94011d3 743 if ((status != 0) || ((count < (length - 1)) && ((REG(SR2.UINT32) & SR2_NACKF) != 0))) {
sahilmgandhi 18:6a4db94011d3 744 /* NACK */
sahilmgandhi 18:6a4db94011d3 745 break;
sahilmgandhi 18:6a4db94011d3 746 }
sahilmgandhi 18:6a4db94011d3 747 }
sahilmgandhi 18:6a4db94011d3 748 count++;
sahilmgandhi 18:6a4db94011d3 749 }
sahilmgandhi 18:6a4db94011d3 750 /* dummy read */
sahilmgandhi 18:6a4db94011d3 751 (void)REG(DRR.UINT32);
sahilmgandhi 18:6a4db94011d3 752 (void)i2c_wait_STOP(obj);
sahilmgandhi 18:6a4db94011d3 753 i2c_set_SR2_NACKF_STOP(obj);
sahilmgandhi 18:6a4db94011d3 754
sahilmgandhi 18:6a4db94011d3 755 return count;
sahilmgandhi 18:6a4db94011d3 756 }
sahilmgandhi 18:6a4db94011d3 757
sahilmgandhi 18:6a4db94011d3 758 void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
sahilmgandhi 18:6a4db94011d3 759 REG(SAR0.UINT32) = (address & 0xfffffffe);
sahilmgandhi 18:6a4db94011d3 760 }