mbed library sources. Supersedes mbed-src.

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

Committer:
Anna Bridge
Date:
Tue Mar 20 17:01:51 2018 +0000
Revision:
183:5166a824ec1a
Parent:
160:d5399cc887bb
Fix mbed lib version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 144:ef7eb2e8f9f7 1 /* mbed Microcontroller Library
<> 144:ef7eb2e8f9f7 2 * Copyright (c) 2015 ARM Limited
<> 144:ef7eb2e8f9f7 3 *
<> 144:ef7eb2e8f9f7 4 * Licensed under the Apache License, Version 2.0 (the "License");
<> 144:ef7eb2e8f9f7 5 * you may not use this file except in compliance with the License.
<> 144:ef7eb2e8f9f7 6 * You may obtain a copy of the License at
<> 144:ef7eb2e8f9f7 7 *
<> 144:ef7eb2e8f9f7 8 * http://www.apache.org/licenses/LICENSE-2.0
<> 144:ef7eb2e8f9f7 9 *
<> 144:ef7eb2e8f9f7 10 * Unless required by applicable law or agreed to in writing, software
<> 144:ef7eb2e8f9f7 11 * distributed under the License is distributed on an "AS IS" BASIS,
<> 144:ef7eb2e8f9f7 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<> 144:ef7eb2e8f9f7 13 * See the License for the specific language governing permissions and
<> 144:ef7eb2e8f9f7 14 * limitations under the License.
<> 144:ef7eb2e8f9f7 15 */
<> 144:ef7eb2e8f9f7 16 #include "i2c_api.h"
<> 144:ef7eb2e8f9f7 17 #include "i2c_def.h"
<> 144:ef7eb2e8f9f7 18 #include "cmsis.h"
<> 144:ef7eb2e8f9f7 19 #include "pinmap.h"
<> 144:ef7eb2e8f9f7 20 #include "mbed_error.h"
<> 160:d5399cc887bb 21 #include "mbed_wait_api.h"
<> 144:ef7eb2e8f9f7 22 /* States of a possibly combined I2C transfer */
<> 144:ef7eb2e8f9f7 23 typedef enum i2c_transfer_state_t {
<> 144:ef7eb2e8f9f7 24 I2C_TRANSFER_SINGLE, /* Non combined transfer */
<> 144:ef7eb2e8f9f7 25 I2C_TRANSFER_COMBINED_FIRST_MESSAGE, /*
<> 144:ef7eb2e8f9f7 26 * First message of a
<> 144:ef7eb2e8f9f7 27 * combined transfer
<> 144:ef7eb2e8f9f7 28 */
<> 144:ef7eb2e8f9f7 29 I2C_TRANSFER_COMBINED_INTERMEDIATE_MESSAGE, /*
<> 144:ef7eb2e8f9f7 30 * Message in the middle
<> 144:ef7eb2e8f9f7 31 * of a combined
<> 144:ef7eb2e8f9f7 32 * transfer
<> 144:ef7eb2e8f9f7 33 */
<> 144:ef7eb2e8f9f7 34 I2C_TRANSFER_COMBINED_LAST_MESSAGE, /*
<> 144:ef7eb2e8f9f7 35 * Last message of a combined
<> 144:ef7eb2e8f9f7 36 * transfer
<> 144:ef7eb2e8f9f7 37 */
<> 144:ef7eb2e8f9f7 38 } i2c_transfer_state_t;
<> 144:ef7eb2e8f9f7 39
<> 144:ef7eb2e8f9f7 40 /*
<> 144:ef7eb2e8f9f7 41 * Driver private data structure that should not be shared by multiple
<> 144:ef7eb2e8f9f7 42 * instances of the driver
<> 144:ef7eb2e8f9f7 43 * (same driver for multiple instances of the IP)
<> 144:ef7eb2e8f9f7 44 */
<> 144:ef7eb2e8f9f7 45 typedef struct private_i2c_t {
<> 144:ef7eb2e8f9f7 46 /* State of a possibly combined ongoing i2c transfer */
<> 144:ef7eb2e8f9f7 47 i2c_transfer_state_t transfer_state;
<> 144:ef7eb2e8f9f7 48 }private_i2c_t;
<> 144:ef7eb2e8f9f7 49
<> 144:ef7eb2e8f9f7 50
<> 144:ef7eb2e8f9f7 51 /*
<> 144:ef7eb2e8f9f7 52 * Retrieve the private data of the instance related to a given IP
<> 144:ef7eb2e8f9f7 53 */
<> 144:ef7eb2e8f9f7 54 static private_i2c_t* get_i2c_private(i2c_t *obj) {
<> 144:ef7eb2e8f9f7 55 static private_i2c_t data0, data1;
<> 144:ef7eb2e8f9f7 56 /*
<> 144:ef7eb2e8f9f7 57 * Select which instance to give using the base
<> 144:ef7eb2e8f9f7 58 * address of registers
<> 144:ef7eb2e8f9f7 59 */
<> 144:ef7eb2e8f9f7 60 switch((intptr_t)obj->i2c) {
<> 144:ef7eb2e8f9f7 61 case I2C0_BASE:
<> 144:ef7eb2e8f9f7 62 return &data0;
<> 144:ef7eb2e8f9f7 63 case I2C1_BASE:
<> 144:ef7eb2e8f9f7 64 return &data1;
<> 144:ef7eb2e8f9f7 65 default:
<> 144:ef7eb2e8f9f7 66 error("i2c driver private data structure not found for this registers base address");
<> 144:ef7eb2e8f9f7 67 return (void*)0;
<> 144:ef7eb2e8f9f7 68 }
<> 144:ef7eb2e8f9f7 69 }
<> 144:ef7eb2e8f9f7 70
<> 144:ef7eb2e8f9f7 71 /*
<> 144:ef7eb2e8f9f7 72 * Infer the current state of a possibly combined transfer
<> 144:ef7eb2e8f9f7 73 * (repeated restart) from the current state and the "stop" parameter
<> 144:ef7eb2e8f9f7 74 * of read and write functions
<> 144:ef7eb2e8f9f7 75 * MUST be called ONCE AND ONLY ONCE at the beginning of i2c transfer
<> 144:ef7eb2e8f9f7 76 * functions (read and write)
<> 144:ef7eb2e8f9f7 77 */
<> 144:ef7eb2e8f9f7 78 static i2c_transfer_state_t update_transfer_state(i2c_t *obj, int stop) {
<> 144:ef7eb2e8f9f7 79 private_i2c_t* private_data = get_i2c_private(obj);
<> 144:ef7eb2e8f9f7 80 i2c_transfer_state_t *state = &private_data->transfer_state;
<> 144:ef7eb2e8f9f7 81
<> 144:ef7eb2e8f9f7 82 /*
<> 144:ef7eb2e8f9f7 83 * Choose the current and next state depending on the current state
<> 144:ef7eb2e8f9f7 84 * This basically implements rising and falling edge detection on
<> 144:ef7eb2e8f9f7 85 * "stop" variable
<> 144:ef7eb2e8f9f7 86 */
<> 144:ef7eb2e8f9f7 87 switch(*state) {
<> 144:ef7eb2e8f9f7 88 /* This is the default state for non restarted repeat transfer */
<> 144:ef7eb2e8f9f7 89 default:
<> 144:ef7eb2e8f9f7 90 case I2C_TRANSFER_SINGLE: /* Not a combined transfer */
<> 144:ef7eb2e8f9f7 91 if (stop) {
<> 144:ef7eb2e8f9f7 92 *state = I2C_TRANSFER_SINGLE;
<> 144:ef7eb2e8f9f7 93 } else {
<> 144:ef7eb2e8f9f7 94 *state = I2C_TRANSFER_COMBINED_FIRST_MESSAGE;
<> 144:ef7eb2e8f9f7 95 }
<> 144:ef7eb2e8f9f7 96 break;
<> 144:ef7eb2e8f9f7 97
<> 144:ef7eb2e8f9f7 98 /* First message of a combined transfer */
<> 144:ef7eb2e8f9f7 99 case I2C_TRANSFER_COMBINED_FIRST_MESSAGE:
<> 144:ef7eb2e8f9f7 100 /* Message in the middle of a combined transfer */
<> 144:ef7eb2e8f9f7 101 case I2C_TRANSFER_COMBINED_INTERMEDIATE_MESSAGE:
<> 144:ef7eb2e8f9f7 102 if (stop) {
<> 144:ef7eb2e8f9f7 103 *state = I2C_TRANSFER_COMBINED_LAST_MESSAGE;
<> 144:ef7eb2e8f9f7 104 } else {
<> 144:ef7eb2e8f9f7 105 *state = I2C_TRANSFER_COMBINED_INTERMEDIATE_MESSAGE;
<> 144:ef7eb2e8f9f7 106 }
<> 144:ef7eb2e8f9f7 107 break;
<> 144:ef7eb2e8f9f7 108
<> 144:ef7eb2e8f9f7 109 /* Last message of a combined transfer */
<> 144:ef7eb2e8f9f7 110 case I2C_TRANSFER_COMBINED_LAST_MESSAGE:
<> 144:ef7eb2e8f9f7 111 if (stop) {
<> 144:ef7eb2e8f9f7 112 *state = I2C_TRANSFER_SINGLE;
<> 144:ef7eb2e8f9f7 113 } else {
<> 144:ef7eb2e8f9f7 114 *state = I2C_TRANSFER_COMBINED_FIRST_MESSAGE;
<> 144:ef7eb2e8f9f7 115 }
<> 144:ef7eb2e8f9f7 116 break;
<> 144:ef7eb2e8f9f7 117 }
<> 144:ef7eb2e8f9f7 118
<> 144:ef7eb2e8f9f7 119 return *state;
<> 144:ef7eb2e8f9f7 120 }
<> 144:ef7eb2e8f9f7 121
<> 144:ef7eb2e8f9f7 122
<> 144:ef7eb2e8f9f7 123 static const PinMap PinMap_I2C_SDA[] = {
<> 144:ef7eb2e8f9f7 124 {SHIELD_SDA, I2C_0, 0},
<> 144:ef7eb2e8f9f7 125 {SENSOR_SDA, I2C_1, 0},
<> 144:ef7eb2e8f9f7 126 {NC, NC , 0}
<> 144:ef7eb2e8f9f7 127 };
<> 144:ef7eb2e8f9f7 128
<> 144:ef7eb2e8f9f7 129 static const PinMap PinMap_I2C_SCL[] = {
<> 144:ef7eb2e8f9f7 130 {SHIELD_SCL, I2C_0, 0},
<> 144:ef7eb2e8f9f7 131 {SENSOR_SCL, I2C_1, 0},
<> 144:ef7eb2e8f9f7 132 {NC, NC, 0}
<> 144:ef7eb2e8f9f7 133 };
<> 144:ef7eb2e8f9f7 134
<> 144:ef7eb2e8f9f7 135 static void clear_isr(i2c_t *obj) {
<> 144:ef7eb2e8f9f7 136 /*
<> 144:ef7eb2e8f9f7 137 * Writing to the IRQ status register clears set bits. Therefore, to
<> 144:ef7eb2e8f9f7 138 * clear indiscriminately, just read the register and write it back.
<> 144:ef7eb2e8f9f7 139 */
<> 144:ef7eb2e8f9f7 140 uint32_t reg = obj->i2c->IRQ_STATUS;
<> 144:ef7eb2e8f9f7 141 obj->i2c->IRQ_STATUS = reg;
<> 144:ef7eb2e8f9f7 142 }
<> 144:ef7eb2e8f9f7 143
<> 144:ef7eb2e8f9f7 144 void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
<> 144:ef7eb2e8f9f7 145 /* Determine the I2C to use */
<> 144:ef7eb2e8f9f7 146 I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
<> 144:ef7eb2e8f9f7 147 I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
<> 144:ef7eb2e8f9f7 148 obj->i2c = (I2C_TypeDef *)pinmap_merge(i2c_sda, i2c_scl);
<> 144:ef7eb2e8f9f7 149
<> 144:ef7eb2e8f9f7 150 if ((int)obj->i2c == NC) {
<> 144:ef7eb2e8f9f7 151 error("I2C pin mapping failed");
<> 144:ef7eb2e8f9f7 152 }
<> 144:ef7eb2e8f9f7 153
<> 144:ef7eb2e8f9f7 154 pinmap_pinout(sda, PinMap_I2C_SDA);
<> 144:ef7eb2e8f9f7 155 pinmap_pinout(scl, PinMap_I2C_SCL);
<> 144:ef7eb2e8f9f7 156
<> 144:ef7eb2e8f9f7 157 /*
<> 144:ef7eb2e8f9f7 158 * Default configuration:
<> 144:ef7eb2e8f9f7 159 * - MS : Master mode
<> 144:ef7eb2e8f9f7 160 * - NEA : Normal (7-bit) addressing
<> 144:ef7eb2e8f9f7 161 * - ACKEN : Send ACKs when reading from slave
<> 144:ef7eb2e8f9f7 162 * - CLR_FIFO : Not a configuration bit => clears the FIFO
<> 144:ef7eb2e8f9f7 163 */
<> 144:ef7eb2e8f9f7 164 uint32_t reg = I2C_CTRL_MS | \
<> 144:ef7eb2e8f9f7 165 I2C_CTRL_NEA | \
<> 144:ef7eb2e8f9f7 166 I2C_CTRL_ACKEN | \
<> 144:ef7eb2e8f9f7 167 I2C_CTRL_CLR_FIFO;
<> 144:ef7eb2e8f9f7 168
<> 144:ef7eb2e8f9f7 169 obj->i2c->CONTROL = reg;
<> 144:ef7eb2e8f9f7 170
<> 144:ef7eb2e8f9f7 171 get_i2c_private(obj)->transfer_state = I2C_TRANSFER_SINGLE;
<> 144:ef7eb2e8f9f7 172
<> 144:ef7eb2e8f9f7 173 i2c_frequency(obj, 100000); /* Default to 100kHz SCL frequency */
<> 144:ef7eb2e8f9f7 174 }
<> 144:ef7eb2e8f9f7 175
<> 144:ef7eb2e8f9f7 176 int i2c_start(i2c_t *obj) {
<> 144:ef7eb2e8f9f7 177 return 0;
<> 144:ef7eb2e8f9f7 178 }
<> 144:ef7eb2e8f9f7 179
<> 144:ef7eb2e8f9f7 180 int i2c_stop(i2c_t *obj) {
<> 144:ef7eb2e8f9f7 181 /* Clear the hardware FIFO */
<> 144:ef7eb2e8f9f7 182 obj->i2c->CONTROL |= I2C_CTRL_CLR_FIFO;
<> 144:ef7eb2e8f9f7 183 /* Clear the HOLD bit used for performing combined transfers */
<> 144:ef7eb2e8f9f7 184 obj->i2c->CONTROL &= ~I2C_CTRL_HOLD;
<> 144:ef7eb2e8f9f7 185 /* Reset the transfer size (read and write) */
<> 144:ef7eb2e8f9f7 186 obj->i2c->TRANSFER_SIZE = 0;
<> 144:ef7eb2e8f9f7 187 /* Clear interrupts */
<> 144:ef7eb2e8f9f7 188 clear_isr(obj);
<> 144:ef7eb2e8f9f7 189 return 0;
<> 144:ef7eb2e8f9f7 190 }
<> 144:ef7eb2e8f9f7 191
<> 144:ef7eb2e8f9f7 192 void i2c_frequency(i2c_t *obj, int hz) {
<> 144:ef7eb2e8f9f7 193 /*
<> 144:ef7eb2e8f9f7 194 * Divider is split in two halfs : A and B
<> 144:ef7eb2e8f9f7 195 * A is 2 bits wide and B is 6 bits wide
<> 144:ef7eb2e8f9f7 196 * The Fscl frequency (SCL clock) is calculated with the following
<> 144:ef7eb2e8f9f7 197 * equation:
<> 144:ef7eb2e8f9f7 198 * Fscl=SystemCoreClock/(22*(A+1)*(B+1))
<> 144:ef7eb2e8f9f7 199 * Here, we only calculate the B divisor which already enables a
<> 144:ef7eb2e8f9f7 200 * wide enough range of values
<> 144:ef7eb2e8f9f7 201 */
<> 144:ef7eb2e8f9f7 202 uint32_t divisor_a = 0; /* Could be changed if a wider range of hz
<> 144:ef7eb2e8f9f7 203 is needed */
<> 144:ef7eb2e8f9f7 204 uint32_t divisor_b = (SystemCoreClock / (22.0 * hz)) - 1;
<> 144:ef7eb2e8f9f7 205
<> 144:ef7eb2e8f9f7 206 /* Clamp the divisors to their maximal value */
<> 144:ef7eb2e8f9f7 207 divisor_a = divisor_a > I2C_CTRL_DIVISOR_A_BIT_MASK ?
<> 144:ef7eb2e8f9f7 208 I2C_CTRL_DIVISOR_A_BIT_MASK : divisor_a;
<> 144:ef7eb2e8f9f7 209 divisor_b = divisor_b > I2C_CTRL_DIVISOR_B_BIT_MASK ?
<> 144:ef7eb2e8f9f7 210 I2C_CTRL_DIVISOR_B_BIT_MASK : divisor_b;
<> 144:ef7eb2e8f9f7 211
<> 144:ef7eb2e8f9f7 212 uint8_t divisor_combinded = (divisor_a & I2C_CTRL_DIVISOR_A_BIT_MASK)
<> 144:ef7eb2e8f9f7 213 | (divisor_b & I2C_CTRL_DIVISOR_B_BIT_MASK);
<> 144:ef7eb2e8f9f7 214
<> 144:ef7eb2e8f9f7 215 obj->i2c->CONTROL = (obj->i2c->CONTROL & ~I2C_CTRL_DIVISORS)
<> 144:ef7eb2e8f9f7 216 | (divisor_combinded << I2C_CTRL_DIVISOR_OFFSET);
<> 144:ef7eb2e8f9f7 217 }
<> 144:ef7eb2e8f9f7 218
<> 144:ef7eb2e8f9f7 219 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
<> 144:ef7eb2e8f9f7 220 int bytes_read = 0;
<> 144:ef7eb2e8f9f7 221 int length_backup = length;
<> 144:ef7eb2e8f9f7 222 char *data_backup = data;
<> 144:ef7eb2e8f9f7 223 obj->last_xfer_address = address;
<> 144:ef7eb2e8f9f7 224 i2c_transfer_state_t transfer_state = update_transfer_state(obj, stop);
<> 144:ef7eb2e8f9f7 225
<> 144:ef7eb2e8f9f7 226 /* Try to write until it finally succeed or times out */
<> 144:ef7eb2e8f9f7 227 int main_timeout = 10;
<> 144:ef7eb2e8f9f7 228 int retry = 0;
<> 144:ef7eb2e8f9f7 229 do {
<> 144:ef7eb2e8f9f7 230 main_timeout--;
<> 144:ef7eb2e8f9f7 231
<> 144:ef7eb2e8f9f7 232 retry = 0;
<> 144:ef7eb2e8f9f7 233 bytes_read = 0;
<> 144:ef7eb2e8f9f7 234 length = length_backup;
<> 144:ef7eb2e8f9f7 235 data = data_backup;
<> 144:ef7eb2e8f9f7 236
<> 144:ef7eb2e8f9f7 237 uint32_t reg = obj->i2c->CONTROL & 0xff7f;
<> 144:ef7eb2e8f9f7 238 reg |= I2C_CTRL_RW | \
<> 144:ef7eb2e8f9f7 239 I2C_CTRL_CLR_FIFO;
<> 144:ef7eb2e8f9f7 240 /*
<> 144:ef7eb2e8f9f7 241 * Only touch the HOLD bit at the beginning of
<> 144:ef7eb2e8f9f7 242 * (possibly combined) transactions
<> 144:ef7eb2e8f9f7 243 */
<> 144:ef7eb2e8f9f7 244 if(transfer_state == I2C_TRANSFER_COMBINED_FIRST_MESSAGE
<> 144:ef7eb2e8f9f7 245 || transfer_state == I2C_TRANSFER_SINGLE) {
<> 144:ef7eb2e8f9f7 246
<> 144:ef7eb2e8f9f7 247 reg |= I2C_CTRL_HOLD;
<> 144:ef7eb2e8f9f7 248 }
<> 144:ef7eb2e8f9f7 249 obj->i2c->CONTROL = reg;
<> 144:ef7eb2e8f9f7 250
<> 144:ef7eb2e8f9f7 251 /* Set the expected number of bytes to be received */
<> 144:ef7eb2e8f9f7 252 if (length > I2C_TRANSFER_SIZE) {
<> 144:ef7eb2e8f9f7 253 error("I2C transfer size too big for the FIFO");
<> 144:ef7eb2e8f9f7 254 }
<> 144:ef7eb2e8f9f7 255 obj->i2c->TRANSFER_SIZE = length & I2C_TRANSFER_SIZE;
<> 144:ef7eb2e8f9f7 256
<> 144:ef7eb2e8f9f7 257 clear_isr(obj);
<> 144:ef7eb2e8f9f7 258
<> 144:ef7eb2e8f9f7 259 /*
<> 144:ef7eb2e8f9f7 260 * Start the transaction by writing address.
<> 144:ef7eb2e8f9f7 261 * Discard the lower bit as it is automatically set
<> 144:ef7eb2e8f9f7 262 * by the controller based on I2C_CTRL_RW bit in CONTROL
<> 144:ef7eb2e8f9f7 263 * register
<> 144:ef7eb2e8f9f7 264 */
<> 144:ef7eb2e8f9f7 265 obj->i2c->ADDRESS = (address & 0xFF) >> 1;
<> 144:ef7eb2e8f9f7 266
<> 144:ef7eb2e8f9f7 267 if(transfer_state == I2C_TRANSFER_COMBINED_LAST_MESSAGE
<> 144:ef7eb2e8f9f7 268 || transfer_state == I2C_TRANSFER_SINGLE) {
<> 144:ef7eb2e8f9f7 269
<> 144:ef7eb2e8f9f7 270 /* Clear the hold bit before reading the DATA register */
<> 144:ef7eb2e8f9f7 271 obj->i2c->CONTROL &= ~I2C_CTRL_HOLD;
<> 144:ef7eb2e8f9f7 272 }
<> 144:ef7eb2e8f9f7 273
<> 144:ef7eb2e8f9f7 274 /* Wait for completion of the address transfer */
<> 144:ef7eb2e8f9f7 275 int completion_timeout = 1000;
<> 144:ef7eb2e8f9f7 276 while (completion_timeout) {
<> 144:ef7eb2e8f9f7 277 completion_timeout--;
<> 144:ef7eb2e8f9f7 278
<> 144:ef7eb2e8f9f7 279 uint32_t irq_status = obj->i2c->IRQ_STATUS;
<> 144:ef7eb2e8f9f7 280 if (irq_status & I2C_IRQ_NACK
<> 144:ef7eb2e8f9f7 281 || irq_status & I2C_IRQ_ARB_LOST) {
<> 144:ef7eb2e8f9f7 282
<> 144:ef7eb2e8f9f7 283 retry = 1;
<> 144:ef7eb2e8f9f7 284 break;
<> 144:ef7eb2e8f9f7 285 }
<> 144:ef7eb2e8f9f7 286
<> 144:ef7eb2e8f9f7 287 if(irq_status & I2C_IRQ_COMP) {
<> 144:ef7eb2e8f9f7 288 break;
<> 144:ef7eb2e8f9f7 289 }
<> 144:ef7eb2e8f9f7 290 }
<> 144:ef7eb2e8f9f7 291
<> 144:ef7eb2e8f9f7 292 /* If retry, jump to the beginning and try again */
<> 144:ef7eb2e8f9f7 293 if (retry || !completion_timeout) {
<> 144:ef7eb2e8f9f7 294 retry = 1;
<> 144:ef7eb2e8f9f7 295 continue;
<> 144:ef7eb2e8f9f7 296 }
<> 144:ef7eb2e8f9f7 297
<> 144:ef7eb2e8f9f7 298 clear_isr(obj);
<> 144:ef7eb2e8f9f7 299
<> 144:ef7eb2e8f9f7 300 /* Read the data from the DATA register */
<> 144:ef7eb2e8f9f7 301 completion_timeout = 1000;
<> 144:ef7eb2e8f9f7 302 while (length && completion_timeout) {
<> 144:ef7eb2e8f9f7 303 completion_timeout--;
<> 144:ef7eb2e8f9f7 304
<> 144:ef7eb2e8f9f7 305 uint32_t irq_status = obj->i2c->IRQ_STATUS;
<> 144:ef7eb2e8f9f7 306 uint32_t status = obj->i2c->STATUS;
<> 144:ef7eb2e8f9f7 307
<> 144:ef7eb2e8f9f7 308 if(irq_status & I2C_IRQ_NACK ||
<> 144:ef7eb2e8f9f7 309 irq_status & I2C_IRQ_ARB_LOST) {
<> 144:ef7eb2e8f9f7 310
<> 144:ef7eb2e8f9f7 311 retry = 1;
<> 144:ef7eb2e8f9f7 312 break;
<> 144:ef7eb2e8f9f7 313 }
<> 144:ef7eb2e8f9f7 314
<> 144:ef7eb2e8f9f7 315 /*
<> 144:ef7eb2e8f9f7 316 * Just wait for RXDV because COMP is only risen at the end
<> 144:ef7eb2e8f9f7 317 * of the transfer
<> 144:ef7eb2e8f9f7 318 */
<> 144:ef7eb2e8f9f7 319 if (status & I2C_STATUS_RXDV) {
<> 144:ef7eb2e8f9f7 320 *data++ = obj->i2c->DATA & 0xFF;
<> 144:ef7eb2e8f9f7 321 length--;
<> 144:ef7eb2e8f9f7 322 bytes_read++;
<> 144:ef7eb2e8f9f7 323 }
<> 144:ef7eb2e8f9f7 324
<> 144:ef7eb2e8f9f7 325 if (irq_status & I2C_IRQ_RX_UNF) {
<> 144:ef7eb2e8f9f7 326 error("Reading more bytes than the I2C transfer size");
<> 144:ef7eb2e8f9f7 327 retry = 1;
<> 144:ef7eb2e8f9f7 328 break;
<> 144:ef7eb2e8f9f7 329 }
<> 144:ef7eb2e8f9f7 330 }
<> 144:ef7eb2e8f9f7 331
<> 144:ef7eb2e8f9f7 332 /* If retry, jump to the beginning and try again */
<> 144:ef7eb2e8f9f7 333 if (retry || !completion_timeout) {
<> 144:ef7eb2e8f9f7 334 retry = 1;
<> 144:ef7eb2e8f9f7 335 continue;
<> 144:ef7eb2e8f9f7 336 }
<> 144:ef7eb2e8f9f7 337 } while(retry && main_timeout);
<> 144:ef7eb2e8f9f7 338
<> 144:ef7eb2e8f9f7 339 if (!main_timeout) {
<> 144:ef7eb2e8f9f7 340 bytes_read = 0;
<> 144:ef7eb2e8f9f7 341 data = data_backup;
<> 144:ef7eb2e8f9f7 342 }
<> 144:ef7eb2e8f9f7 343
<> 144:ef7eb2e8f9f7 344 obj->i2c->CONTROL |= I2C_CTRL_CLR_FIFO;
<> 144:ef7eb2e8f9f7 345 clear_isr(obj);
<> 144:ef7eb2e8f9f7 346 return bytes_read;
<> 144:ef7eb2e8f9f7 347 }
<> 144:ef7eb2e8f9f7 348
<> 144:ef7eb2e8f9f7 349 int i2c_write(i2c_t *obj, int address, const char *data, int length,
<> 144:ef7eb2e8f9f7 350 int stop) {
<> 144:ef7eb2e8f9f7 351
<> 144:ef7eb2e8f9f7 352 int bytes_written = 0;
<> 144:ef7eb2e8f9f7 353 int length_backup = length;
<> 144:ef7eb2e8f9f7 354 const char *data_backup = data;
<> 144:ef7eb2e8f9f7 355 obj->last_xfer_address = address;
<> 144:ef7eb2e8f9f7 356 i2c_transfer_state_t transfer_state = update_transfer_state(obj, stop);
<> 144:ef7eb2e8f9f7 357
<> 144:ef7eb2e8f9f7 358 /* Try to write until it finally succeed or times out */
<> 144:ef7eb2e8f9f7 359 int main_timeout = 10;
<> 144:ef7eb2e8f9f7 360 int retry = 0;
<> 144:ef7eb2e8f9f7 361 do {
<> 144:ef7eb2e8f9f7 362 main_timeout--;
<> 144:ef7eb2e8f9f7 363
<> 144:ef7eb2e8f9f7 364 retry = 0;
<> 144:ef7eb2e8f9f7 365 bytes_written = 0;
<> 144:ef7eb2e8f9f7 366 length = length_backup;
<> 144:ef7eb2e8f9f7 367 data = data_backup;
<> 144:ef7eb2e8f9f7 368
<> 144:ef7eb2e8f9f7 369 /* Read the defined bits in the control register */
<> 144:ef7eb2e8f9f7 370 uint32_t reg = obj->i2c->CONTROL & 0xff7f;
<> 144:ef7eb2e8f9f7 371 reg |= I2C_CTRL_CLR_FIFO;
<> 144:ef7eb2e8f9f7 372 reg &= ~I2C_CTRL_RW;
<> 144:ef7eb2e8f9f7 373
<> 144:ef7eb2e8f9f7 374 /*
<> 144:ef7eb2e8f9f7 375 * Only touch the HOLD bit at the beginning of
<> 144:ef7eb2e8f9f7 376 * (possibly combined) transactions
<> 144:ef7eb2e8f9f7 377 */
<> 144:ef7eb2e8f9f7 378 if(transfer_state == I2C_TRANSFER_COMBINED_FIRST_MESSAGE
<> 144:ef7eb2e8f9f7 379 || transfer_state == I2C_TRANSFER_SINGLE) {
<> 144:ef7eb2e8f9f7 380
<> 144:ef7eb2e8f9f7 381 reg |= I2C_CTRL_HOLD;
<> 144:ef7eb2e8f9f7 382 }
<> 144:ef7eb2e8f9f7 383 obj->i2c->CONTROL = reg;
<> 144:ef7eb2e8f9f7 384
<> 144:ef7eb2e8f9f7 385 clear_isr(obj);
<> 144:ef7eb2e8f9f7 386
<> 144:ef7eb2e8f9f7 387 /* Set the expected number of bytes to be transmitted */
<> 144:ef7eb2e8f9f7 388 if (length > I2C_TRANSFER_SIZE) {
<> 144:ef7eb2e8f9f7 389 error("I2C transfer size too big for the FIFO");
<> 144:ef7eb2e8f9f7 390 }
<> 144:ef7eb2e8f9f7 391
<> 144:ef7eb2e8f9f7 392 /* Set the expected number of bytes to be transmitted */
<> 144:ef7eb2e8f9f7 393 obj->i2c->TRANSFER_SIZE = length & I2C_TRANSFER_SIZE;
<> 144:ef7eb2e8f9f7 394
<> 144:ef7eb2e8f9f7 395 /*
<> 144:ef7eb2e8f9f7 396 * Write the address, triggering the start of the transfer
<> 144:ef7eb2e8f9f7 397 * Discard the lower bit as it is automatically set
<> 144:ef7eb2e8f9f7 398 * by the controller based on I2C_CTRL_RW bit in CONTROL
<> 144:ef7eb2e8f9f7 399 * register
<> 144:ef7eb2e8f9f7 400 */
<> 144:ef7eb2e8f9f7 401 obj->i2c->ADDRESS = (address & 0xFF) >> 1;
<> 144:ef7eb2e8f9f7 402
<> 144:ef7eb2e8f9f7 403 /* Send the data bytes */
<> 144:ef7eb2e8f9f7 404 int write_timeout = 1000 + length;
<> 144:ef7eb2e8f9f7 405 while (length && write_timeout) {
<> 144:ef7eb2e8f9f7 406 write_timeout--;
<> 144:ef7eb2e8f9f7 407 uint32_t irq_status = obj->i2c->IRQ_STATUS;
<> 144:ef7eb2e8f9f7 408 /* If overflow, undo last step */
<> 144:ef7eb2e8f9f7 409 if (irq_status & I2C_IRQ_TX_OVF) {
<> 144:ef7eb2e8f9f7 410 *data--;
<> 144:ef7eb2e8f9f7 411 length++;
<> 144:ef7eb2e8f9f7 412 bytes_written--;
<> 144:ef7eb2e8f9f7 413 /* Clear the bit by writing 1 to it */
<> 144:ef7eb2e8f9f7 414 obj->i2c->IRQ_STATUS |= I2C_IRQ_TX_OVF;
<> 144:ef7eb2e8f9f7 415 }
<> 144:ef7eb2e8f9f7 416
<> 144:ef7eb2e8f9f7 417 if (irq_status & I2C_IRQ_NACK
<> 144:ef7eb2e8f9f7 418 || irq_status & I2C_IRQ_ARB_LOST) {
<> 144:ef7eb2e8f9f7 419
<> 144:ef7eb2e8f9f7 420 retry = 1;
<> 144:ef7eb2e8f9f7 421 break;
<> 144:ef7eb2e8f9f7 422 }
<> 144:ef7eb2e8f9f7 423
<> 144:ef7eb2e8f9f7 424 obj->i2c->DATA = *data++;
<> 144:ef7eb2e8f9f7 425 length--;
<> 144:ef7eb2e8f9f7 426 bytes_written++;
<> 144:ef7eb2e8f9f7 427 }
<> 144:ef7eb2e8f9f7 428
<> 144:ef7eb2e8f9f7 429 /* If retry, jump to the beginning and try again */
<> 144:ef7eb2e8f9f7 430 if (retry || !write_timeout) {
<> 144:ef7eb2e8f9f7 431 retry = 1;
<> 144:ef7eb2e8f9f7 432 continue;
<> 144:ef7eb2e8f9f7 433 }
<> 144:ef7eb2e8f9f7 434
<> 144:ef7eb2e8f9f7 435 if(transfer_state == I2C_TRANSFER_COMBINED_LAST_MESSAGE
<> 144:ef7eb2e8f9f7 436 || transfer_state == I2C_TRANSFER_SINGLE) {
<> 144:ef7eb2e8f9f7 437 /*
<> 144:ef7eb2e8f9f7 438 * Clear the hold bit to signify the end
<> 144:ef7eb2e8f9f7 439 * of the write sequence
<> 144:ef7eb2e8f9f7 440 */
<> 144:ef7eb2e8f9f7 441 obj->i2c->CONTROL &= ~I2C_CTRL_HOLD;
<> 144:ef7eb2e8f9f7 442 }
<> 144:ef7eb2e8f9f7 443
<> 144:ef7eb2e8f9f7 444
<> 144:ef7eb2e8f9f7 445 /* Wait for transfer completion */
<> 144:ef7eb2e8f9f7 446 int completion_timeout = 1000;
<> 144:ef7eb2e8f9f7 447 while (completion_timeout) {
<> 144:ef7eb2e8f9f7 448 completion_timeout--;
<> 144:ef7eb2e8f9f7 449
<> 144:ef7eb2e8f9f7 450 uint32_t irq_status = obj->i2c->IRQ_STATUS;
<> 144:ef7eb2e8f9f7 451 if(irq_status & I2C_IRQ_NACK
<> 144:ef7eb2e8f9f7 452 || irq_status & I2C_IRQ_ARB_LOST) {
<> 144:ef7eb2e8f9f7 453 retry = 1;
<> 144:ef7eb2e8f9f7 454 break;
<> 144:ef7eb2e8f9f7 455 }
<> 144:ef7eb2e8f9f7 456 if(irq_status & I2C_IRQ_COMP) {
<> 144:ef7eb2e8f9f7 457 break;
<> 144:ef7eb2e8f9f7 458 }
<> 144:ef7eb2e8f9f7 459 }
<> 144:ef7eb2e8f9f7 460
<> 144:ef7eb2e8f9f7 461 /* If retry, jump to the beginning and try again */
<> 144:ef7eb2e8f9f7 462 if (retry || !completion_timeout) {
<> 144:ef7eb2e8f9f7 463 continue;
<> 144:ef7eb2e8f9f7 464 }
<> 144:ef7eb2e8f9f7 465
<> 144:ef7eb2e8f9f7 466 obj->i2c->CONTROL |= I2C_CTRL_CLR_FIFO;
<> 144:ef7eb2e8f9f7 467 clear_isr(obj);
<> 144:ef7eb2e8f9f7 468 } while(retry && main_timeout);
<> 144:ef7eb2e8f9f7 469
<> 144:ef7eb2e8f9f7 470 return bytes_written;
<> 144:ef7eb2e8f9f7 471 }
<> 144:ef7eb2e8f9f7 472
<> 144:ef7eb2e8f9f7 473 void i2c_reset(i2c_t *obj) {
<> 144:ef7eb2e8f9f7 474 i2c_stop(obj);
<> 144:ef7eb2e8f9f7 475 }
<> 144:ef7eb2e8f9f7 476
<> 144:ef7eb2e8f9f7 477 int i2c_byte_read(i2c_t *obj, int last) {
<> 144:ef7eb2e8f9f7 478 char i2c_ret = 0;
<> 144:ef7eb2e8f9f7 479 i2c_read(obj, obj->last_xfer_address, &i2c_ret, 1, last);
<> 144:ef7eb2e8f9f7 480 return i2c_ret;
<> 144:ef7eb2e8f9f7 481 }
<> 144:ef7eb2e8f9f7 482
<> 144:ef7eb2e8f9f7 483 int i2c_byte_write(i2c_t *obj, int data) {
<> 144:ef7eb2e8f9f7 484 /* Store the number of written bytes */
<> 144:ef7eb2e8f9f7 485 uint32_t wb = i2c_write(obj, obj->last_xfer_address, (char*)&data, 1, 0);
<> 144:ef7eb2e8f9f7 486 if (wb == 1)
<> 144:ef7eb2e8f9f7 487 return 1;
<> 144:ef7eb2e8f9f7 488 else
<> 144:ef7eb2e8f9f7 489 return 0;
<> 144:ef7eb2e8f9f7 490 }
<> 144:ef7eb2e8f9f7 491
<> 144:ef7eb2e8f9f7 492 void i2c_slave_mode(i2c_t *obj, int enable_slave) {
<> 144:ef7eb2e8f9f7 493 }
<> 144:ef7eb2e8f9f7 494
<> 144:ef7eb2e8f9f7 495 int i2c_slave_receive(i2c_t *obj) {
<> 144:ef7eb2e8f9f7 496 return 0;
<> 144:ef7eb2e8f9f7 497 }
<> 144:ef7eb2e8f9f7 498
<> 144:ef7eb2e8f9f7 499 int i2c_slave_read(i2c_t *obj, char *data, int length) {
<> 144:ef7eb2e8f9f7 500 return 0;
<> 144:ef7eb2e8f9f7 501 }
<> 144:ef7eb2e8f9f7 502
<> 144:ef7eb2e8f9f7 503 int i2c_slave_write(i2c_t *obj, const char *data, int length) {
<> 144:ef7eb2e8f9f7 504 return 0;
<> 144:ef7eb2e8f9f7 505 }
<> 144:ef7eb2e8f9f7 506
<> 144:ef7eb2e8f9f7 507 void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
<> 144:ef7eb2e8f9f7 508 }