mbed library sources. Supersedes mbed-src.

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

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

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AnnaBridge 189:f392fc9709a3 1 /* mbed Microcontroller Library
AnnaBridge 189:f392fc9709a3 2 * Copyright (c) 2018 GigaDevice Semiconductor Inc.
AnnaBridge 189:f392fc9709a3 3 *
AnnaBridge 189:f392fc9709a3 4 * SPDX-License-Identifier: Apache-2.0
AnnaBridge 189:f392fc9709a3 5 *
AnnaBridge 189:f392fc9709a3 6 * Licensed under the Apache License, Version 2.0 (the "License");
AnnaBridge 189:f392fc9709a3 7 * you may not use this file except in compliance with the License.
AnnaBridge 189:f392fc9709a3 8 * You may obtain a copy of the License at
AnnaBridge 189:f392fc9709a3 9 *
AnnaBridge 189:f392fc9709a3 10 * http://www.apache.org/licenses/LICENSE-2.0
AnnaBridge 189:f392fc9709a3 11 *
AnnaBridge 189:f392fc9709a3 12 * Unless required by applicable law or agreed to in writing, software
AnnaBridge 189:f392fc9709a3 13 * distributed under the License is distributed on an "AS IS" BASIS,
AnnaBridge 189:f392fc9709a3 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
AnnaBridge 189:f392fc9709a3 15 * See the License for the specific language governing permissions and
AnnaBridge 189:f392fc9709a3 16 * limitations under the License.
AnnaBridge 189:f392fc9709a3 17 */
AnnaBridge 189:f392fc9709a3 18
AnnaBridge 189:f392fc9709a3 19 #include "mbed_assert.h"
AnnaBridge 189:f392fc9709a3 20 #include "i2c_api.h"
AnnaBridge 189:f392fc9709a3 21
AnnaBridge 189:f392fc9709a3 22 #if DEVICE_I2C
AnnaBridge 189:f392fc9709a3 23
AnnaBridge 189:f392fc9709a3 24 #include "cmsis.h"
AnnaBridge 189:f392fc9709a3 25 #include "pinmap.h"
AnnaBridge 189:f392fc9709a3 26 #include "PeripheralPins.h"
AnnaBridge 189:f392fc9709a3 27
AnnaBridge 189:f392fc9709a3 28 #if DEVICE_I2C_ASYNCH
AnnaBridge 189:f392fc9709a3 29 #define I2C_S(obj) (struct i2c_s *) (&((obj)->i2c))
AnnaBridge 189:f392fc9709a3 30 #else
AnnaBridge 189:f392fc9709a3 31 #define I2C_S(obj) (struct i2c_s *) (obj)
AnnaBridge 189:f392fc9709a3 32 #endif
AnnaBridge 189:f392fc9709a3 33
AnnaBridge 189:f392fc9709a3 34 #define BUSY_TIMEOUT ((SystemCoreClock / obj_s->freq) * 2 * 10)
AnnaBridge 189:f392fc9709a3 35 #define FLAG_TIMEOUT (0x1000U)
AnnaBridge 189:f392fc9709a3 36
AnnaBridge 189:f392fc9709a3 37 /** Reset I2C peripheral by hardware method. Most of the implementation enable RCU reset.
AnnaBridge 189:f392fc9709a3 38 *
AnnaBridge 189:f392fc9709a3 39 * @param obj The I2C object
AnnaBridge 189:f392fc9709a3 40 */
AnnaBridge 189:f392fc9709a3 41 static void i2c_hw_reset(i2c_t *obj)
AnnaBridge 189:f392fc9709a3 42 {
AnnaBridge 189:f392fc9709a3 43 struct i2c_s *obj_s = I2C_S(obj);
AnnaBridge 189:f392fc9709a3 44
AnnaBridge 189:f392fc9709a3 45 switch (obj_s->i2c) {
AnnaBridge 189:f392fc9709a3 46 case I2C_0:
AnnaBridge 189:f392fc9709a3 47 rcu_periph_reset_enable(RCU_I2C0RST);
AnnaBridge 189:f392fc9709a3 48 rcu_periph_reset_disable(RCU_I2C0RST);
AnnaBridge 189:f392fc9709a3 49 break;
AnnaBridge 189:f392fc9709a3 50
AnnaBridge 189:f392fc9709a3 51 case I2C_1:
AnnaBridge 189:f392fc9709a3 52 rcu_periph_reset_enable(RCU_I2C1RST);
AnnaBridge 189:f392fc9709a3 53 rcu_periph_reset_disable(RCU_I2C1RST);
AnnaBridge 189:f392fc9709a3 54 break;
AnnaBridge 189:f392fc9709a3 55 }
AnnaBridge 189:f392fc9709a3 56 }
AnnaBridge 189:f392fc9709a3 57
AnnaBridge 189:f392fc9709a3 58 /** Initialize the I2C peripheral. It sets the default parameters for I2C
AnnaBridge 189:f392fc9709a3 59 * peripheral, and configures its specifieds pins.
AnnaBridge 189:f392fc9709a3 60 *
AnnaBridge 189:f392fc9709a3 61 * @param obj The I2C object
AnnaBridge 189:f392fc9709a3 62 * @param sda The sda pin
AnnaBridge 189:f392fc9709a3 63 * @param scl The scl pin
AnnaBridge 189:f392fc9709a3 64 */
AnnaBridge 189:f392fc9709a3 65 void i2c_init(i2c_t *obj, PinName sda, PinName scl)
AnnaBridge 189:f392fc9709a3 66 {
AnnaBridge 189:f392fc9709a3 67 struct i2c_s *obj_s = I2C_S(obj);
AnnaBridge 189:f392fc9709a3 68
AnnaBridge 189:f392fc9709a3 69 /* find the I2C by pins */
AnnaBridge 189:f392fc9709a3 70 uint32_t i2c_sda = pinmap_peripheral(sda, PinMap_I2C_SDA);
AnnaBridge 189:f392fc9709a3 71 uint32_t i2c_scl = pinmap_peripheral(scl, PinMap_I2C_SCL);
AnnaBridge 189:f392fc9709a3 72
AnnaBridge 189:f392fc9709a3 73 obj_s->sda = sda;
AnnaBridge 189:f392fc9709a3 74 obj_s->scl = scl;
AnnaBridge 189:f392fc9709a3 75 obj_s->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
AnnaBridge 189:f392fc9709a3 76 MBED_ASSERT(obj_s->i2c != (I2CName)NC);
AnnaBridge 189:f392fc9709a3 77
AnnaBridge 189:f392fc9709a3 78 switch (obj_s->i2c) {
AnnaBridge 189:f392fc9709a3 79 case I2C_0:
AnnaBridge 189:f392fc9709a3 80 /* enable I2C0 clock and configure the pins of I2C0 */
AnnaBridge 189:f392fc9709a3 81 obj_s->index = 0;
AnnaBridge 189:f392fc9709a3 82 rcu_periph_clock_enable(RCU_I2C0);
AnnaBridge 189:f392fc9709a3 83
AnnaBridge 189:f392fc9709a3 84 break;
AnnaBridge 189:f392fc9709a3 85
AnnaBridge 189:f392fc9709a3 86 case I2C_1:
AnnaBridge 189:f392fc9709a3 87 /* enable I2C1 clock and configure the pins of I2C1 */
AnnaBridge 189:f392fc9709a3 88 obj_s->index = 1;
AnnaBridge 189:f392fc9709a3 89 rcu_periph_clock_enable(RCU_I2C1);
AnnaBridge 189:f392fc9709a3 90
AnnaBridge 189:f392fc9709a3 91 break;
AnnaBridge 189:f392fc9709a3 92
AnnaBridge 189:f392fc9709a3 93 default:
AnnaBridge 189:f392fc9709a3 94 break;
AnnaBridge 189:f392fc9709a3 95 }
AnnaBridge 189:f392fc9709a3 96
AnnaBridge 189:f392fc9709a3 97 /* configure the pins of I2C */
AnnaBridge 189:f392fc9709a3 98 pinmap_pinout(sda, PinMap_I2C_SDA);
AnnaBridge 189:f392fc9709a3 99 pinmap_pinout(scl, PinMap_I2C_SCL);
AnnaBridge 189:f392fc9709a3 100
AnnaBridge 189:f392fc9709a3 101 /* 100 KHz as the default I2C frequence */
AnnaBridge 189:f392fc9709a3 102 i2c_frequency(obj, 100000);
AnnaBridge 189:f392fc9709a3 103
AnnaBridge 189:f392fc9709a3 104 obj_s->state = (operation_state_enum)I2C_STATE_NONE;
AnnaBridge 189:f392fc9709a3 105 obj_s->previous_state_mode = I2C_STATE_NONE;
AnnaBridge 189:f392fc9709a3 106 obj_s->global_trans_option = I2C_FIRST_AND_LAST_FRAME;
AnnaBridge 189:f392fc9709a3 107
AnnaBridge 189:f392fc9709a3 108 #if DEVICE_I2CSLAVE
AnnaBridge 189:f392fc9709a3 109 /* I2C master by default */
AnnaBridge 189:f392fc9709a3 110 obj_s->slave = 0;
AnnaBridge 189:f392fc9709a3 111 #endif
AnnaBridge 189:f392fc9709a3 112 }
AnnaBridge 189:f392fc9709a3 113
AnnaBridge 189:f392fc9709a3 114 /** Configure the I2C frequency
AnnaBridge 189:f392fc9709a3 115 *
AnnaBridge 189:f392fc9709a3 116 * @param obj The I2C object
AnnaBridge 189:f392fc9709a3 117 * @param hz Frequency in Hz
AnnaBridge 189:f392fc9709a3 118 */
AnnaBridge 189:f392fc9709a3 119 void i2c_frequency(i2c_t *obj, int hz)
AnnaBridge 189:f392fc9709a3 120 {
AnnaBridge 189:f392fc9709a3 121 int timeout;
AnnaBridge 189:f392fc9709a3 122 struct i2c_s *obj_s = I2C_S(obj);
AnnaBridge 189:f392fc9709a3 123
AnnaBridge 189:f392fc9709a3 124 /* wait until I2C_FLAG_I2CBSY flag is reset */
AnnaBridge 189:f392fc9709a3 125 timeout = BUSY_TIMEOUT;
AnnaBridge 189:f392fc9709a3 126 while ((i2c_flag_get(obj_s->i2c, I2C_FLAG_I2CBSY)) && (--timeout != 0));
AnnaBridge 189:f392fc9709a3 127
AnnaBridge 189:f392fc9709a3 128 /* reset to clear pending flags */
AnnaBridge 189:f392fc9709a3 129 i2c_hw_reset(obj);
AnnaBridge 189:f392fc9709a3 130
AnnaBridge 189:f392fc9709a3 131 /* disable I2C peripheral */
AnnaBridge 189:f392fc9709a3 132 i2c_disable(obj_s->i2c);
AnnaBridge 189:f392fc9709a3 133
AnnaBridge 189:f392fc9709a3 134 /* configure I2C frequence */
AnnaBridge 189:f392fc9709a3 135 i2c_clock_config(obj_s->i2c, hz, I2C_DTCY_2);
AnnaBridge 189:f392fc9709a3 136
AnnaBridge 189:f392fc9709a3 137 /* configure I2C address mode and slave address */
AnnaBridge 189:f392fc9709a3 138 i2c_mode_addr_config(obj_s->i2c, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0);
AnnaBridge 189:f392fc9709a3 139
AnnaBridge 189:f392fc9709a3 140 /* enable I2C peripheral */
AnnaBridge 189:f392fc9709a3 141 i2c_enable(obj_s->i2c);
AnnaBridge 189:f392fc9709a3 142 }
AnnaBridge 189:f392fc9709a3 143
AnnaBridge 189:f392fc9709a3 144 /** Reset I2C peripheral. TODO: The action here. Most of the implementation sends stop()
AnnaBridge 189:f392fc9709a3 145 *
AnnaBridge 189:f392fc9709a3 146 * @param obj The I2C object
AnnaBridge 189:f392fc9709a3 147 */
AnnaBridge 189:f392fc9709a3 148 void i2c_reset(i2c_t *obj)
AnnaBridge 189:f392fc9709a3 149 {
AnnaBridge 189:f392fc9709a3 150 i2c_stop(obj);
AnnaBridge 189:f392fc9709a3 151 }
AnnaBridge 189:f392fc9709a3 152
AnnaBridge 189:f392fc9709a3 153 /** Send START command
AnnaBridge 189:f392fc9709a3 154 *
AnnaBridge 189:f392fc9709a3 155 * @param obj The I2C object
AnnaBridge 189:f392fc9709a3 156 */
AnnaBridge 189:f392fc9709a3 157 int i2c_start(i2c_t *obj)
AnnaBridge 189:f392fc9709a3 158 {
AnnaBridge 189:f392fc9709a3 159 int timeout;
AnnaBridge 189:f392fc9709a3 160 struct i2c_s *obj_s = I2C_S(obj);
AnnaBridge 189:f392fc9709a3 161
AnnaBridge 189:f392fc9709a3 162 /* clear I2C_FLAG_AERR Flag */
AnnaBridge 189:f392fc9709a3 163 i2c_flag_clear(obj_s->i2c, I2C_FLAG_AERR);
AnnaBridge 189:f392fc9709a3 164
AnnaBridge 189:f392fc9709a3 165 /* wait until I2C_FLAG_I2CBSY flag is reset */
AnnaBridge 189:f392fc9709a3 166 timeout = FLAG_TIMEOUT;
AnnaBridge 189:f392fc9709a3 167 while ((i2c_flag_get(obj_s->i2c, I2C_FLAG_I2CBSY)) == SET) {
AnnaBridge 189:f392fc9709a3 168 if ((timeout--) == 0) {
AnnaBridge 189:f392fc9709a3 169 return (int)GD_BUSY;
AnnaBridge 189:f392fc9709a3 170 }
AnnaBridge 189:f392fc9709a3 171 }
AnnaBridge 189:f392fc9709a3 172
AnnaBridge 189:f392fc9709a3 173 /* ensure the i2c has been stopped */
AnnaBridge 189:f392fc9709a3 174 timeout = FLAG_TIMEOUT;
AnnaBridge 189:f392fc9709a3 175 while ((I2C_CTL0(obj_s->i2c) & I2C_CTL0_STOP) == I2C_CTL0_STOP) {
AnnaBridge 189:f392fc9709a3 176 if ((timeout--) == 0) {
AnnaBridge 189:f392fc9709a3 177 return (int)GD_ERROR;
AnnaBridge 189:f392fc9709a3 178 }
AnnaBridge 189:f392fc9709a3 179 }
AnnaBridge 189:f392fc9709a3 180
AnnaBridge 189:f392fc9709a3 181 /* generate a START condition */
AnnaBridge 189:f392fc9709a3 182 i2c_start_on_bus(obj_s->i2c);
AnnaBridge 189:f392fc9709a3 183
AnnaBridge 189:f392fc9709a3 184 /* ensure the i2c has been started successfully */
AnnaBridge 189:f392fc9709a3 185 timeout = FLAG_TIMEOUT;
AnnaBridge 189:f392fc9709a3 186 while ((i2c_flag_get(obj_s->i2c, I2C_FLAG_SBSEND)) == RESET) {
AnnaBridge 189:f392fc9709a3 187 if ((timeout--) == 0) {
AnnaBridge 189:f392fc9709a3 188 return (int)GD_ERROR;
AnnaBridge 189:f392fc9709a3 189 }
AnnaBridge 189:f392fc9709a3 190 }
AnnaBridge 189:f392fc9709a3 191
AnnaBridge 189:f392fc9709a3 192 return (int)GD_OK;
AnnaBridge 189:f392fc9709a3 193 }
AnnaBridge 189:f392fc9709a3 194
AnnaBridge 189:f392fc9709a3 195 /** Send STOP command
AnnaBridge 189:f392fc9709a3 196 *
AnnaBridge 189:f392fc9709a3 197 * @param obj The I2C object
AnnaBridge 189:f392fc9709a3 198 */
AnnaBridge 189:f392fc9709a3 199 int i2c_stop(i2c_t *obj)
AnnaBridge 189:f392fc9709a3 200 {
AnnaBridge 189:f392fc9709a3 201 struct i2c_s *obj_s = I2C_S(obj);
AnnaBridge 189:f392fc9709a3 202
AnnaBridge 189:f392fc9709a3 203 /* generate a STOP condition */
AnnaBridge 189:f392fc9709a3 204 i2c_stop_on_bus(obj_s->i2c);
AnnaBridge 189:f392fc9709a3 205
AnnaBridge 189:f392fc9709a3 206 /* wait for STOP bit reset */
AnnaBridge 189:f392fc9709a3 207 while ((I2C_CTL0(obj_s->i2c) & I2C_CTL0_STOP));
AnnaBridge 189:f392fc9709a3 208
AnnaBridge 189:f392fc9709a3 209 return 0;
AnnaBridge 189:f392fc9709a3 210 }
AnnaBridge 189:f392fc9709a3 211
AnnaBridge 189:f392fc9709a3 212 /** Read one byte
AnnaBridge 189:f392fc9709a3 213 *
AnnaBridge 189:f392fc9709a3 214 * @param obj The I2C object
AnnaBridge 189:f392fc9709a3 215 * @param last Acknoledge
AnnaBridge 189:f392fc9709a3 216 * @return The read byte
AnnaBridge 189:f392fc9709a3 217 */
AnnaBridge 189:f392fc9709a3 218 int i2c_byte_read(i2c_t *obj, int last)
AnnaBridge 189:f392fc9709a3 219 {
AnnaBridge 189:f392fc9709a3 220 int timeout;
AnnaBridge 189:f392fc9709a3 221 struct i2c_s *obj_s = I2C_S(obj);
AnnaBridge 189:f392fc9709a3 222
AnnaBridge 189:f392fc9709a3 223 if (last) {
AnnaBridge 189:f392fc9709a3 224 /* disable acknowledge */
AnnaBridge 189:f392fc9709a3 225 i2c_ack_config(obj_s->i2c, I2C_ACK_DISABLE);
AnnaBridge 189:f392fc9709a3 226 } else {
AnnaBridge 189:f392fc9709a3 227 /* enable acknowledge */
AnnaBridge 189:f392fc9709a3 228 i2c_ack_config(obj_s->i2c, I2C_ACK_ENABLE);
AnnaBridge 189:f392fc9709a3 229 }
AnnaBridge 189:f392fc9709a3 230
AnnaBridge 189:f392fc9709a3 231 /* wait until the byte is received */
AnnaBridge 189:f392fc9709a3 232 timeout = FLAG_TIMEOUT;
AnnaBridge 189:f392fc9709a3 233 while ((i2c_flag_get(obj_s->i2c, I2C_FLAG_RBNE)) == RESET) {
AnnaBridge 189:f392fc9709a3 234 if ((timeout--) == 0) {
AnnaBridge 189:f392fc9709a3 235 return -1;
AnnaBridge 189:f392fc9709a3 236 }
AnnaBridge 189:f392fc9709a3 237 }
AnnaBridge 189:f392fc9709a3 238
AnnaBridge 189:f392fc9709a3 239 return (int)I2C_DATA(obj_s->i2c);
AnnaBridge 189:f392fc9709a3 240 }
AnnaBridge 189:f392fc9709a3 241
AnnaBridge 189:f392fc9709a3 242 /** Write one byte
AnnaBridge 189:f392fc9709a3 243 *
AnnaBridge 189:f392fc9709a3 244 * @param obj The I2C object
AnnaBridge 189:f392fc9709a3 245 * @param data Byte to be written
AnnaBridge 189:f392fc9709a3 246 * @return 0 if NAK was received, 1 if ACK was received, 2 for timeout.
AnnaBridge 189:f392fc9709a3 247 */
AnnaBridge 189:f392fc9709a3 248 int i2c_byte_write(i2c_t *obj, int data)
AnnaBridge 189:f392fc9709a3 249 {
AnnaBridge 189:f392fc9709a3 250 int timeout;
AnnaBridge 189:f392fc9709a3 251 struct i2c_s *obj_s = I2C_S(obj);
AnnaBridge 189:f392fc9709a3 252
AnnaBridge 189:f392fc9709a3 253 I2C_DATA(obj_s->i2c) = (uint8_t)data;
AnnaBridge 189:f392fc9709a3 254
AnnaBridge 189:f392fc9709a3 255 /* wait until the byte is transmitted */
AnnaBridge 189:f392fc9709a3 256 timeout = FLAG_TIMEOUT;
AnnaBridge 189:f392fc9709a3 257 while (((i2c_flag_get(obj_s->i2c, I2C_FLAG_TBE)) == RESET) &&
AnnaBridge 189:f392fc9709a3 258 ((i2c_flag_get(obj_s->i2c, I2C_FLAG_BTC)) == RESET)) {
AnnaBridge 189:f392fc9709a3 259 if ((timeout--) == 0) {
AnnaBridge 189:f392fc9709a3 260 return 2;
AnnaBridge 189:f392fc9709a3 261 }
AnnaBridge 189:f392fc9709a3 262 }
AnnaBridge 189:f392fc9709a3 263
AnnaBridge 189:f392fc9709a3 264 return 1;
AnnaBridge 189:f392fc9709a3 265 }
AnnaBridge 189:f392fc9709a3 266
AnnaBridge 189:f392fc9709a3 267 /** Blocking reading data
AnnaBridge 189:f392fc9709a3 268 *
AnnaBridge 189:f392fc9709a3 269 * @param obj The I2C object
AnnaBridge 189:f392fc9709a3 270 * @param address 7-bit address (last bit is 1)
AnnaBridge 189:f392fc9709a3 271 * @param data The buffer for receiving
AnnaBridge 189:f392fc9709a3 272 * @param length Number of bytes to read
AnnaBridge 189:f392fc9709a3 273 * @param stop Stop to be generated after the transfer is done
AnnaBridge 189:f392fc9709a3 274 * @return Number of read bytes
AnnaBridge 189:f392fc9709a3 275 */
AnnaBridge 189:f392fc9709a3 276 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
AnnaBridge 189:f392fc9709a3 277 {
AnnaBridge 189:f392fc9709a3 278 struct i2c_s *obj_s = I2C_S(obj);
AnnaBridge 189:f392fc9709a3 279 uint32_t count = 0U;
AnnaBridge 189:f392fc9709a3 280 int timeout = 0;
AnnaBridge 189:f392fc9709a3 281
AnnaBridge 189:f392fc9709a3 282 if (obj_s->global_trans_option == I2C_FIRST_AND_LAST_FRAME ||
AnnaBridge 189:f392fc9709a3 283 obj_s->global_trans_option == I2C_LAST_FRAME) {
AnnaBridge 189:f392fc9709a3 284 if (stop) {
AnnaBridge 189:f392fc9709a3 285 obj_s->global_trans_option = I2C_FIRST_AND_LAST_FRAME;
AnnaBridge 189:f392fc9709a3 286 } else {
AnnaBridge 189:f392fc9709a3 287 obj_s->global_trans_option = I2C_FIRST_FRAME;
AnnaBridge 189:f392fc9709a3 288 }
AnnaBridge 189:f392fc9709a3 289 } else if (obj_s->global_trans_option == I2C_FIRST_FRAME ||
AnnaBridge 189:f392fc9709a3 290 obj_s->global_trans_option == I2C_NEXT_FRAME) {
AnnaBridge 189:f392fc9709a3 291 if (stop) {
AnnaBridge 189:f392fc9709a3 292 obj_s->global_trans_option = I2C_LAST_FRAME;
AnnaBridge 189:f392fc9709a3 293 } else {
AnnaBridge 189:f392fc9709a3 294 obj_s->global_trans_option = I2C_NEXT_FRAME;
AnnaBridge 189:f392fc9709a3 295 }
AnnaBridge 189:f392fc9709a3 296 }
AnnaBridge 189:f392fc9709a3 297
AnnaBridge 189:f392fc9709a3 298 if (obj_s->global_trans_option == I2C_FIRST_AND_LAST_FRAME || obj_s->global_trans_option == I2C_FIRST_FRAME) {
AnnaBridge 189:f392fc9709a3 299 /* wait until I2C_FLAG_I2CBSY flag is reset */
AnnaBridge 189:f392fc9709a3 300 timeout = FLAG_TIMEOUT;
AnnaBridge 189:f392fc9709a3 301 while ((i2c_flag_get(obj_s->i2c, I2C_FLAG_I2CBSY)) == SET) {
AnnaBridge 189:f392fc9709a3 302 if ((timeout--) == 0) {
AnnaBridge 189:f392fc9709a3 303 i2c_stop(obj);
AnnaBridge 189:f392fc9709a3 304 return I2C_ERROR_BUS_BUSY;
AnnaBridge 189:f392fc9709a3 305 }
AnnaBridge 189:f392fc9709a3 306 }
AnnaBridge 189:f392fc9709a3 307 }
AnnaBridge 189:f392fc9709a3 308
AnnaBridge 189:f392fc9709a3 309 if (obj_s->global_trans_option == I2C_FIRST_AND_LAST_FRAME || obj_s->global_trans_option == I2C_FIRST_FRAME ||
AnnaBridge 189:f392fc9709a3 310 obj_s->previous_state_mode != I2C_STATE_MASTER_BUSY_RX) {
AnnaBridge 189:f392fc9709a3 311 /* generate a START condition */
AnnaBridge 189:f392fc9709a3 312 i2c_start_on_bus(obj_s->i2c);
AnnaBridge 189:f392fc9709a3 313
AnnaBridge 189:f392fc9709a3 314 /* ensure the i2c has been started successfully */
AnnaBridge 189:f392fc9709a3 315 timeout = FLAG_TIMEOUT;
AnnaBridge 189:f392fc9709a3 316 while ((i2c_flag_get(obj_s->i2c, I2C_FLAG_SBSEND)) == RESET) {
AnnaBridge 189:f392fc9709a3 317 if ((timeout--) == 0) {
AnnaBridge 189:f392fc9709a3 318 i2c_stop(obj);
AnnaBridge 189:f392fc9709a3 319 return I2C_ERROR_BUS_BUSY;
AnnaBridge 189:f392fc9709a3 320 }
AnnaBridge 189:f392fc9709a3 321 }
AnnaBridge 189:f392fc9709a3 322
AnnaBridge 189:f392fc9709a3 323 /* send slave address */
AnnaBridge 189:f392fc9709a3 324 i2c_master_addressing(obj_s->i2c, address, I2C_RECEIVER);
AnnaBridge 189:f392fc9709a3 325
AnnaBridge 189:f392fc9709a3 326 if (1 == length) {
AnnaBridge 189:f392fc9709a3 327 /* disable acknowledge */
AnnaBridge 189:f392fc9709a3 328 i2c_ack_config(obj_s->i2c, I2C_ACK_DISABLE);
AnnaBridge 189:f392fc9709a3 329 /* send a stop condition to I2C bus*/
AnnaBridge 189:f392fc9709a3 330 } else if (2 == length) {
AnnaBridge 189:f392fc9709a3 331 /* send a NACK for the next data byte which will be received into the shift register */
AnnaBridge 189:f392fc9709a3 332 i2c_ackpos_config(obj_s->i2c, I2C_ACKPOS_NEXT);
AnnaBridge 189:f392fc9709a3 333 /* disable acknowledge */
AnnaBridge 189:f392fc9709a3 334 i2c_ack_config(obj_s->i2c, I2C_ACK_DISABLE);
AnnaBridge 189:f392fc9709a3 335 } else {
AnnaBridge 189:f392fc9709a3 336 /* enable acknowledge */
AnnaBridge 189:f392fc9709a3 337 i2c_ack_config(obj_s->i2c, I2C_ACK_ENABLE);
AnnaBridge 189:f392fc9709a3 338 }
AnnaBridge 189:f392fc9709a3 339
AnnaBridge 189:f392fc9709a3 340 /* wait until I2C_FLAG_ADDSEND flag is set */
AnnaBridge 189:f392fc9709a3 341 while (!i2c_flag_get(obj_s->i2c, I2C_FLAG_ADDSEND)) {
AnnaBridge 189:f392fc9709a3 342 timeout++;
AnnaBridge 189:f392fc9709a3 343 if (timeout > 100000) {
AnnaBridge 189:f392fc9709a3 344 i2c_stop(obj);
AnnaBridge 189:f392fc9709a3 345 return I2C_ERROR_NO_SLAVE;
AnnaBridge 189:f392fc9709a3 346 }
AnnaBridge 189:f392fc9709a3 347 }
AnnaBridge 189:f392fc9709a3 348
AnnaBridge 189:f392fc9709a3 349 /* clear ADDSEND */
AnnaBridge 189:f392fc9709a3 350 i2c_flag_clear(obj_s->i2c, I2C_FLAG_ADDSEND);
AnnaBridge 189:f392fc9709a3 351 }
AnnaBridge 189:f392fc9709a3 352
AnnaBridge 189:f392fc9709a3 353 obj_s->state = (operation_state_enum)I2C_STATE_MASTER_BUSY_RX;
AnnaBridge 189:f392fc9709a3 354
AnnaBridge 189:f392fc9709a3 355 for (count = 0; count < length; count++) {
AnnaBridge 189:f392fc9709a3 356 if (length > 2 && count == length - 3) {
AnnaBridge 189:f392fc9709a3 357 while (RESET == i2c_flag_get(obj_s->i2c, I2C_FLAG_BTC));
AnnaBridge 189:f392fc9709a3 358 i2c_ack_config(obj_s->i2c, I2C_ACK_DISABLE);
AnnaBridge 189:f392fc9709a3 359 } else if (2 == length && count == 0) {
AnnaBridge 189:f392fc9709a3 360 while (RESET == i2c_flag_get(obj_s->i2c, I2C_FLAG_BTC));
AnnaBridge 189:f392fc9709a3 361 }
AnnaBridge 189:f392fc9709a3 362
AnnaBridge 189:f392fc9709a3 363 while (RESET == i2c_flag_get(obj_s->i2c, I2C_FLAG_RBNE));
AnnaBridge 189:f392fc9709a3 364 data[count] = i2c_data_receive(obj_s->i2c);
AnnaBridge 189:f392fc9709a3 365 }
AnnaBridge 189:f392fc9709a3 366
AnnaBridge 189:f392fc9709a3 367 obj_s->previous_state_mode = obj_s->state;
AnnaBridge 189:f392fc9709a3 368
AnnaBridge 189:f392fc9709a3 369 /* if not sequential read, then send stop */
AnnaBridge 189:f392fc9709a3 370 if (stop) {
AnnaBridge 189:f392fc9709a3 371 i2c_stop(obj);
AnnaBridge 189:f392fc9709a3 372 }
AnnaBridge 189:f392fc9709a3 373
AnnaBridge 189:f392fc9709a3 374 return count;
AnnaBridge 189:f392fc9709a3 375 }
AnnaBridge 189:f392fc9709a3 376
AnnaBridge 189:f392fc9709a3 377 /** Blocking sending data
AnnaBridge 189:f392fc9709a3 378 *
AnnaBridge 189:f392fc9709a3 379 * @param obj The I2C object
AnnaBridge 189:f392fc9709a3 380 * @param address 7-bit address (last bit is 0)
AnnaBridge 189:f392fc9709a3 381 * @param data The buffer for sending
AnnaBridge 189:f392fc9709a3 382 * @param length Number of bytes to write
AnnaBridge 189:f392fc9709a3 383 * @param stop Stop to be generated after the transfer is done
AnnaBridge 189:f392fc9709a3 384 * @return
AnnaBridge 189:f392fc9709a3 385 * zero or non-zero - Number of written bytes
AnnaBridge 189:f392fc9709a3 386 * negative - I2C_ERROR_XXX status
AnnaBridge 189:f392fc9709a3 387 */
AnnaBridge 189:f392fc9709a3 388 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
AnnaBridge 189:f392fc9709a3 389 {
AnnaBridge 189:f392fc9709a3 390 struct i2c_s *obj_s = I2C_S(obj);
AnnaBridge 189:f392fc9709a3 391 gd_status_enum status = GD_OK;
AnnaBridge 189:f392fc9709a3 392 uint32_t count = 0;
AnnaBridge 189:f392fc9709a3 393 int timeout = 0;
AnnaBridge 189:f392fc9709a3 394
AnnaBridge 189:f392fc9709a3 395 if (obj_s->global_trans_option == I2C_FIRST_AND_LAST_FRAME ||
AnnaBridge 189:f392fc9709a3 396 obj_s->global_trans_option == I2C_LAST_FRAME) {
AnnaBridge 189:f392fc9709a3 397 if (stop) {
AnnaBridge 189:f392fc9709a3 398 obj_s->global_trans_option = I2C_FIRST_AND_LAST_FRAME;
AnnaBridge 189:f392fc9709a3 399 } else {
AnnaBridge 189:f392fc9709a3 400 obj_s->global_trans_option = I2C_FIRST_FRAME;
AnnaBridge 189:f392fc9709a3 401 }
AnnaBridge 189:f392fc9709a3 402 } else if (obj_s->global_trans_option == I2C_FIRST_FRAME ||
AnnaBridge 189:f392fc9709a3 403 obj_s->global_trans_option == I2C_NEXT_FRAME) {
AnnaBridge 189:f392fc9709a3 404 if (stop) {
AnnaBridge 189:f392fc9709a3 405 obj_s->global_trans_option = I2C_LAST_FRAME;
AnnaBridge 189:f392fc9709a3 406 } else {
AnnaBridge 189:f392fc9709a3 407 obj_s->global_trans_option = I2C_NEXT_FRAME;
AnnaBridge 189:f392fc9709a3 408 }
AnnaBridge 189:f392fc9709a3 409 }
AnnaBridge 189:f392fc9709a3 410
AnnaBridge 189:f392fc9709a3 411 if (obj_s->global_trans_option == I2C_FIRST_AND_LAST_FRAME || obj_s->global_trans_option == I2C_FIRST_FRAME) {
AnnaBridge 189:f392fc9709a3 412 /* wait until I2C_FLAG_I2CBSY flag is reset */
AnnaBridge 189:f392fc9709a3 413 timeout = FLAG_TIMEOUT;
AnnaBridge 189:f392fc9709a3 414 while ((i2c_flag_get(obj_s->i2c, I2C_FLAG_I2CBSY)) == SET) {
AnnaBridge 189:f392fc9709a3 415 if ((timeout--) == 0) {
AnnaBridge 189:f392fc9709a3 416 i2c_stop(obj);
AnnaBridge 189:f392fc9709a3 417 return I2C_ERROR_BUS_BUSY;
AnnaBridge 189:f392fc9709a3 418 }
AnnaBridge 189:f392fc9709a3 419 }
AnnaBridge 189:f392fc9709a3 420 }
AnnaBridge 189:f392fc9709a3 421
AnnaBridge 189:f392fc9709a3 422 if (obj_s->global_trans_option == I2C_FIRST_AND_LAST_FRAME || obj_s->global_trans_option == I2C_FIRST_FRAME ||
AnnaBridge 189:f392fc9709a3 423 obj_s->previous_state_mode != I2C_STATE_MASTER_BUSY_TX) {
AnnaBridge 189:f392fc9709a3 424 /* generate a START condition */
AnnaBridge 189:f392fc9709a3 425 i2c_start_on_bus(obj_s->i2c);
AnnaBridge 189:f392fc9709a3 426
AnnaBridge 189:f392fc9709a3 427 /* ensure the i2c has been started successfully */
AnnaBridge 189:f392fc9709a3 428 timeout = FLAG_TIMEOUT;
AnnaBridge 189:f392fc9709a3 429 while ((i2c_flag_get(obj_s->i2c, I2C_FLAG_SBSEND)) == RESET) {
AnnaBridge 189:f392fc9709a3 430 if ((timeout--) == 0) {
AnnaBridge 189:f392fc9709a3 431 i2c_stop(obj);
AnnaBridge 189:f392fc9709a3 432 return I2C_ERROR_BUS_BUSY;
AnnaBridge 189:f392fc9709a3 433 }
AnnaBridge 189:f392fc9709a3 434 }
AnnaBridge 189:f392fc9709a3 435
AnnaBridge 189:f392fc9709a3 436 /* send slave address */
AnnaBridge 189:f392fc9709a3 437 i2c_master_addressing(obj_s->i2c, address, I2C_TRANSMITTER);
AnnaBridge 189:f392fc9709a3 438
AnnaBridge 189:f392fc9709a3 439 /* wait until I2C_FLAG_ADDSEND flag is set */
AnnaBridge 189:f392fc9709a3 440 while (!i2c_flag_get(obj_s->i2c, I2C_FLAG_ADDSEND)) {
AnnaBridge 189:f392fc9709a3 441 timeout++;
AnnaBridge 189:f392fc9709a3 442 if (timeout > 100000) {
AnnaBridge 189:f392fc9709a3 443 i2c_stop(obj);
AnnaBridge 189:f392fc9709a3 444 return I2C_ERROR_NO_SLAVE;
AnnaBridge 189:f392fc9709a3 445 }
AnnaBridge 189:f392fc9709a3 446 }
AnnaBridge 189:f392fc9709a3 447
AnnaBridge 189:f392fc9709a3 448 /* clear ADDSEND */
AnnaBridge 189:f392fc9709a3 449 i2c_flag_clear(obj_s->i2c, I2C_FLAG_ADDSEND);
AnnaBridge 189:f392fc9709a3 450 }
AnnaBridge 189:f392fc9709a3 451
AnnaBridge 189:f392fc9709a3 452 obj_s->state = (operation_state_enum)I2C_STATE_MASTER_BUSY_TX;
AnnaBridge 189:f392fc9709a3 453
AnnaBridge 189:f392fc9709a3 454 for (count = 0; count < length; count++) {
AnnaBridge 189:f392fc9709a3 455 status = (gd_status_enum)i2c_byte_write(obj, data[count]);
AnnaBridge 189:f392fc9709a3 456 if (status != 1) {
AnnaBridge 189:f392fc9709a3 457 i2c_stop(obj);
AnnaBridge 189:f392fc9709a3 458 return count;
AnnaBridge 189:f392fc9709a3 459 }
AnnaBridge 189:f392fc9709a3 460 }
AnnaBridge 189:f392fc9709a3 461
AnnaBridge 189:f392fc9709a3 462 obj_s->previous_state_mode = obj_s->state;
AnnaBridge 189:f392fc9709a3 463
AnnaBridge 189:f392fc9709a3 464 /* if not sequential write, then send stop */
AnnaBridge 189:f392fc9709a3 465 if (stop) {
AnnaBridge 189:f392fc9709a3 466 i2c_stop(obj);
AnnaBridge 189:f392fc9709a3 467 }
AnnaBridge 189:f392fc9709a3 468
AnnaBridge 189:f392fc9709a3 469 return count;
AnnaBridge 189:f392fc9709a3 470 }
AnnaBridge 189:f392fc9709a3 471
AnnaBridge 189:f392fc9709a3 472 #if DEVICE_I2CSLAVE
AnnaBridge 189:f392fc9709a3 473
AnnaBridge 189:f392fc9709a3 474 /** Configure I2C address.
AnnaBridge 189:f392fc9709a3 475 * @param obj The I2C object
AnnaBridge 189:f392fc9709a3 476 * @param idx Currently not used
AnnaBridge 189:f392fc9709a3 477 * @param address The address to be set
AnnaBridge 189:f392fc9709a3 478 * @param mask Currently not used
AnnaBridge 189:f392fc9709a3 479 */
AnnaBridge 189:f392fc9709a3 480 void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask)
AnnaBridge 189:f392fc9709a3 481 {
AnnaBridge 189:f392fc9709a3 482 struct i2c_s *obj_s = I2C_S(obj);
AnnaBridge 189:f392fc9709a3 483
AnnaBridge 189:f392fc9709a3 484 /* disable I2C peripheral */
AnnaBridge 189:f392fc9709a3 485 i2c_disable(obj_s->i2c);
AnnaBridge 189:f392fc9709a3 486 /* I2C clock configure */
AnnaBridge 189:f392fc9709a3 487 i2c_clock_config(obj_s->i2c, 100000, I2C_DTCY_2);
AnnaBridge 189:f392fc9709a3 488 /* I2C address configure */
AnnaBridge 189:f392fc9709a3 489 i2c_mode_addr_config(obj_s->i2c, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, address);
AnnaBridge 189:f392fc9709a3 490 /* enable I2C0 */
AnnaBridge 189:f392fc9709a3 491 i2c_enable(obj_s->i2c);
AnnaBridge 189:f392fc9709a3 492 /* enable acknowledge */
AnnaBridge 189:f392fc9709a3 493 i2c_ack_config(obj_s->i2c, I2C_ACK_ENABLE);
AnnaBridge 189:f392fc9709a3 494 }
AnnaBridge 189:f392fc9709a3 495
AnnaBridge 189:f392fc9709a3 496 /** Configure I2C as slave or master.
AnnaBridge 189:f392fc9709a3 497 * @param obj The I2C object
AnnaBridge 189:f392fc9709a3 498 * @param enable_slave Enable i2c hardware so you can receive events with ::i2c_slave_receive
AnnaBridge 189:f392fc9709a3 499 * @return non-zero if a value is available
AnnaBridge 189:f392fc9709a3 500 */
AnnaBridge 189:f392fc9709a3 501 void i2c_slave_mode(i2c_t *obj, int enable_slave)
AnnaBridge 189:f392fc9709a3 502 {
AnnaBridge 189:f392fc9709a3 503 struct i2c_s *obj_s = I2C_S(obj);
AnnaBridge 189:f392fc9709a3 504
AnnaBridge 189:f392fc9709a3 505 if (enable_slave) {
AnnaBridge 189:f392fc9709a3 506 obj_s->slave = 1;
AnnaBridge 189:f392fc9709a3 507 } else {
AnnaBridge 189:f392fc9709a3 508 obj_s->slave = 0;
AnnaBridge 189:f392fc9709a3 509 }
AnnaBridge 189:f392fc9709a3 510 }
AnnaBridge 189:f392fc9709a3 511
AnnaBridge 189:f392fc9709a3 512 /* the same as the definition in I2CSlave.h class I2CSlave */
AnnaBridge 189:f392fc9709a3 513 #define NoData 0 /* the slave has not been addressed */
AnnaBridge 189:f392fc9709a3 514 #define ReadAddressed 1 /* the master has requested a read from this slave (slave as transmitter) */
AnnaBridge 189:f392fc9709a3 515 #define WriteGeneral 2 /* the master is writing to all slave */
AnnaBridge 189:f392fc9709a3 516 #define WriteAddressed 3 /* the master is writing to this slave (slave as receiver) */
AnnaBridge 189:f392fc9709a3 517
AnnaBridge 189:f392fc9709a3 518 /** Check to see if the I2C slave has been addressed.
AnnaBridge 189:f392fc9709a3 519 * @param obj The I2C object
AnnaBridge 189:f392fc9709a3 520 * @return The status - 1 - read addresses, 2 - write to all slaves,
AnnaBridge 189:f392fc9709a3 521 * 3 write addressed, 0 - the slave has not been addressed
AnnaBridge 189:f392fc9709a3 522 */
AnnaBridge 189:f392fc9709a3 523 int i2c_slave_receive(i2c_t *obj)
AnnaBridge 189:f392fc9709a3 524 {
AnnaBridge 189:f392fc9709a3 525 struct i2c_s *obj_s = I2C_S(obj);
AnnaBridge 189:f392fc9709a3 526 int ret = NoData;
AnnaBridge 189:f392fc9709a3 527
AnnaBridge 189:f392fc9709a3 528 i2c_ack_config(obj_s->i2c, I2C_ACK_ENABLE);
AnnaBridge 189:f392fc9709a3 529
AnnaBridge 189:f392fc9709a3 530 if (i2c_flag_get(obj_s->i2c, I2C_FLAG_ADDSEND)) {
AnnaBridge 189:f392fc9709a3 531 i2c_ack_config(obj_s->i2c, I2C_ACK_ENABLE);
AnnaBridge 189:f392fc9709a3 532 if (i2c_flag_get(obj_s->i2c, I2C_FLAG_RXGC)) {
AnnaBridge 189:f392fc9709a3 533 ret = WriteGeneral;
AnnaBridge 189:f392fc9709a3 534 }
AnnaBridge 189:f392fc9709a3 535
AnnaBridge 189:f392fc9709a3 536 if (i2c_flag_get(obj_s->i2c, I2C_FLAG_TRS)) {
AnnaBridge 189:f392fc9709a3 537 ret = ReadAddressed;
AnnaBridge 189:f392fc9709a3 538 } else {
AnnaBridge 189:f392fc9709a3 539 ret = WriteAddressed;
AnnaBridge 189:f392fc9709a3 540 }
AnnaBridge 189:f392fc9709a3 541 }
AnnaBridge 189:f392fc9709a3 542
AnnaBridge 189:f392fc9709a3 543 i2c_ack_config(obj_s->i2c, I2C_ACK_ENABLE);
AnnaBridge 189:f392fc9709a3 544
AnnaBridge 189:f392fc9709a3 545 return (ret);
AnnaBridge 189:f392fc9709a3 546 }
AnnaBridge 189:f392fc9709a3 547
AnnaBridge 189:f392fc9709a3 548 /** Configure I2C as slave or master.
AnnaBridge 189:f392fc9709a3 549 * @param obj The I2C object
AnnaBridge 189:f392fc9709a3 550 * @param data The buffer for receiving
AnnaBridge 189:f392fc9709a3 551 * @param length Number of bytes to read
AnnaBridge 189:f392fc9709a3 552 * @return non-zero if a value is available
AnnaBridge 189:f392fc9709a3 553 */
AnnaBridge 189:f392fc9709a3 554 int i2c_slave_read(i2c_t *obj, char *data, int length)
AnnaBridge 189:f392fc9709a3 555 {
AnnaBridge 189:f392fc9709a3 556 struct i2c_s *obj_s = I2C_S(obj);
AnnaBridge 189:f392fc9709a3 557 int count = 0;
AnnaBridge 189:f392fc9709a3 558 int timeout = 0;
AnnaBridge 189:f392fc9709a3 559
AnnaBridge 189:f392fc9709a3 560 i2c_ack_config(obj_s->i2c, I2C_ACK_ENABLE);
AnnaBridge 189:f392fc9709a3 561
AnnaBridge 189:f392fc9709a3 562 /* wait until ADDSEND bit is set */
AnnaBridge 189:f392fc9709a3 563 while (!i2c_flag_get(obj_s->i2c, I2C_FLAG_ADDSEND)) {
AnnaBridge 189:f392fc9709a3 564 timeout++;
AnnaBridge 189:f392fc9709a3 565 if (timeout > 100000) {
AnnaBridge 189:f392fc9709a3 566 return -1;
AnnaBridge 189:f392fc9709a3 567 }
AnnaBridge 189:f392fc9709a3 568 }
AnnaBridge 189:f392fc9709a3 569 /* clear ADDSEND bit */
AnnaBridge 189:f392fc9709a3 570 i2c_flag_clear(obj_s->i2c, I2C_FLAG_ADDSEND);
AnnaBridge 189:f392fc9709a3 571
AnnaBridge 189:f392fc9709a3 572 while (0 < length) {
AnnaBridge 189:f392fc9709a3 573 /* wait until the RBNE bit is set */
AnnaBridge 189:f392fc9709a3 574 timeout = 0;
AnnaBridge 189:f392fc9709a3 575 while (!i2c_flag_get(obj_s->i2c, I2C_FLAG_RBNE)) {
AnnaBridge 189:f392fc9709a3 576 timeout++;
AnnaBridge 189:f392fc9709a3 577 if (timeout > 100000) {
AnnaBridge 189:f392fc9709a3 578 return -1;
AnnaBridge 189:f392fc9709a3 579 }
AnnaBridge 189:f392fc9709a3 580 }
AnnaBridge 189:f392fc9709a3 581 *data = i2c_data_receive(obj_s->i2c);
AnnaBridge 189:f392fc9709a3 582 data++;
AnnaBridge 189:f392fc9709a3 583 length--;
AnnaBridge 189:f392fc9709a3 584 count++;
AnnaBridge 189:f392fc9709a3 585 }
AnnaBridge 189:f392fc9709a3 586 /* wait until the STPDET bit is set */
AnnaBridge 189:f392fc9709a3 587 timeout = 0;
AnnaBridge 189:f392fc9709a3 588 while (!i2c_flag_get(obj_s->i2c, I2C_FLAG_STPDET)) {
AnnaBridge 189:f392fc9709a3 589 timeout++;
AnnaBridge 189:f392fc9709a3 590 if (timeout > 100) {
AnnaBridge 189:f392fc9709a3 591 return count;
AnnaBridge 189:f392fc9709a3 592 }
AnnaBridge 189:f392fc9709a3 593 }
AnnaBridge 189:f392fc9709a3 594 /* clear the STPDET bit */
AnnaBridge 189:f392fc9709a3 595 i2c_enable(obj_s->i2c);
AnnaBridge 189:f392fc9709a3 596
AnnaBridge 189:f392fc9709a3 597 i2c_ack_config(obj_s->i2c, I2C_ACK_DISABLE);
AnnaBridge 189:f392fc9709a3 598
AnnaBridge 189:f392fc9709a3 599 return count;
AnnaBridge 189:f392fc9709a3 600 }
AnnaBridge 189:f392fc9709a3 601
AnnaBridge 189:f392fc9709a3 602 /** Configure I2C as slave or master.
AnnaBridge 189:f392fc9709a3 603 * @param obj The I2C object
AnnaBridge 189:f392fc9709a3 604 * @param data The buffer for sending
AnnaBridge 189:f392fc9709a3 605 * @param length Number of bytes to write
AnnaBridge 189:f392fc9709a3 606 * @return non-zero if a value is available
AnnaBridge 189:f392fc9709a3 607 */
AnnaBridge 189:f392fc9709a3 608 int i2c_slave_write(i2c_t *obj, const char *data, int length)
AnnaBridge 189:f392fc9709a3 609 {
AnnaBridge 189:f392fc9709a3 610 struct i2c_s *obj_s = I2C_S(obj);
AnnaBridge 189:f392fc9709a3 611 int count = 0;
AnnaBridge 189:f392fc9709a3 612 int timeout = 0;
AnnaBridge 189:f392fc9709a3 613
AnnaBridge 189:f392fc9709a3 614 i2c_ack_config(obj_s->i2c, I2C_ACK_ENABLE);
AnnaBridge 189:f392fc9709a3 615 /* wait until ADDSEND bit is set */
AnnaBridge 189:f392fc9709a3 616 while (!i2c_flag_get(obj_s->i2c, I2C_FLAG_ADDSEND)) {
AnnaBridge 189:f392fc9709a3 617 timeout++;
AnnaBridge 189:f392fc9709a3 618 if (timeout > 100000) {
AnnaBridge 189:f392fc9709a3 619 return -1;
AnnaBridge 189:f392fc9709a3 620 }
AnnaBridge 189:f392fc9709a3 621 }
AnnaBridge 189:f392fc9709a3 622 /* clear ADDSEND bit */
AnnaBridge 189:f392fc9709a3 623 i2c_flag_clear(obj_s->i2c, I2C_FLAG_ADDSEND);
AnnaBridge 189:f392fc9709a3 624 while (length > 0) {
AnnaBridge 189:f392fc9709a3 625 /* wait until the TBE bit is set */
AnnaBridge 189:f392fc9709a3 626 timeout = 0;
AnnaBridge 189:f392fc9709a3 627 while (!i2c_flag_get(obj_s->i2c, I2C_FLAG_TBE)) {
AnnaBridge 189:f392fc9709a3 628 timeout++;
AnnaBridge 189:f392fc9709a3 629 if (timeout > 100000) {
AnnaBridge 189:f392fc9709a3 630 return -1;
AnnaBridge 189:f392fc9709a3 631 }
AnnaBridge 189:f392fc9709a3 632 }
AnnaBridge 189:f392fc9709a3 633 i2c_data_transmit(obj_s->i2c, *data);
AnnaBridge 189:f392fc9709a3 634 data++;
AnnaBridge 189:f392fc9709a3 635 length--;
AnnaBridge 189:f392fc9709a3 636 count++;
AnnaBridge 189:f392fc9709a3 637 }
AnnaBridge 189:f392fc9709a3 638 /* the master doesn't acknowledge for the last byte */
AnnaBridge 189:f392fc9709a3 639 timeout = 0;
AnnaBridge 189:f392fc9709a3 640 while (!i2c_flag_get(obj_s->i2c, I2C_FLAG_AERR)) {
AnnaBridge 189:f392fc9709a3 641 timeout++;
AnnaBridge 189:f392fc9709a3 642 if (timeout > 100000) {
AnnaBridge 189:f392fc9709a3 643 return -1;
AnnaBridge 189:f392fc9709a3 644 }
AnnaBridge 189:f392fc9709a3 645 }
AnnaBridge 189:f392fc9709a3 646 /* clear the bit of AERR */
AnnaBridge 189:f392fc9709a3 647 i2c_flag_clear(obj_s->i2c, I2C_FLAG_AERR);
AnnaBridge 189:f392fc9709a3 648 /* disable acknowledge */
AnnaBridge 189:f392fc9709a3 649 i2c_ack_config(obj_s->i2c, I2C_ACK_DISABLE);
AnnaBridge 189:f392fc9709a3 650
AnnaBridge 189:f392fc9709a3 651 return count;
AnnaBridge 189:f392fc9709a3 652 }
AnnaBridge 189:f392fc9709a3 653 #endif /* DEVICE_I2CSLAVE */
AnnaBridge 189:f392fc9709a3 654
AnnaBridge 189:f392fc9709a3 655 #endif /* DEVICE_I2C */