mbed library sources

Dependents:   Encrypted my_mbed lklk CyaSSL_DTLS_Cellular ... more

Superseded

This library was superseded by mbed-dev - https://os.mbed.com/users/mbed_official/code/mbed-dev/.

Development branch of the mbed library sources. This library is kept in synch with the latest changes from the mbed SDK and it is not guaranteed to work.

If you are looking for a stable and tested release, please import one of the official mbed library releases:

Import librarymbed

The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.

Committer:
bogdanm
Date:
Wed Aug 07 16:43:59 2013 +0300
Revision:
15:4892fe388435
Child:
34:a3c7023e45de
Added LPC4088 target and interrupt chaining code

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bogdanm 15:4892fe388435 1 /* mbed Microcontroller Library
bogdanm 15:4892fe388435 2 * Copyright (c) 2006-2013 ARM Limited
bogdanm 15:4892fe388435 3 *
bogdanm 15:4892fe388435 4 * Licensed under the Apache License, Version 2.0 (the "License");
bogdanm 15:4892fe388435 5 * you may not use this file except in compliance with the License.
bogdanm 15:4892fe388435 6 * You may obtain a copy of the License at
bogdanm 15:4892fe388435 7 *
bogdanm 15:4892fe388435 8 * http://www.apache.org/licenses/LICENSE-2.0
bogdanm 15:4892fe388435 9 *
bogdanm 15:4892fe388435 10 * Unless required by applicable law or agreed to in writing, software
bogdanm 15:4892fe388435 11 * distributed under the License is distributed on an "AS IS" BASIS,
bogdanm 15:4892fe388435 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
bogdanm 15:4892fe388435 13 * See the License for the specific language governing permissions and
bogdanm 15:4892fe388435 14 * limitations under the License.
bogdanm 15:4892fe388435 15 */
bogdanm 15:4892fe388435 16 #include "i2c_api.h"
bogdanm 15:4892fe388435 17 #include "cmsis.h"
bogdanm 15:4892fe388435 18 #include "pinmap.h"
bogdanm 15:4892fe388435 19 #include "error.h"
bogdanm 15:4892fe388435 20
bogdanm 15:4892fe388435 21 static const PinMap PinMap_I2C_SDA[] = {
bogdanm 15:4892fe388435 22 {P0_0 , I2C_1, 3},
bogdanm 15:4892fe388435 23 {P0_10, I2C_2, 2},
bogdanm 15:4892fe388435 24 {P0_19, I2C_1, 3},
bogdanm 15:4892fe388435 25 {P0_27, I2C_0, 1},
bogdanm 15:4892fe388435 26 {P1_15, I2C_2, 3},
bogdanm 15:4892fe388435 27 {P1_30, I2C_0, 4},
bogdanm 15:4892fe388435 28 {P2_14, I2C_1, 2},
bogdanm 15:4892fe388435 29 {P2_30, I2C_2, 2},
bogdanm 15:4892fe388435 30 {P4_20, I2C_2, 4},
bogdanm 15:4892fe388435 31 {P5_2, I2C_0, 5},
bogdanm 15:4892fe388435 32 {NC , NC , 0}
bogdanm 15:4892fe388435 33 };
bogdanm 15:4892fe388435 34
bogdanm 15:4892fe388435 35 static const PinMap PinMap_I2C_SCL[] = {
bogdanm 15:4892fe388435 36 {P0_1 , I2C_1, 3},
bogdanm 15:4892fe388435 37 {P0_11, I2C_2, 2},
bogdanm 15:4892fe388435 38 {P0_20, I2C_1, 3},
bogdanm 15:4892fe388435 39 {P0_28, I2C_0, 1},
bogdanm 15:4892fe388435 40 {P1_31, I2C_0, 4},
bogdanm 15:4892fe388435 41 {P2_15, I2C_1, 2},
bogdanm 15:4892fe388435 42 {P2_31, I2C_2, 2},
bogdanm 15:4892fe388435 43 {P4_21, I2C_2, 2},
bogdanm 15:4892fe388435 44 {P4_29, I2C_2, 4},
bogdanm 15:4892fe388435 45 {P5_3, I2C_0, 5},
bogdanm 15:4892fe388435 46 {NC , NC, 0}
bogdanm 15:4892fe388435 47 };
bogdanm 15:4892fe388435 48
bogdanm 15:4892fe388435 49 #define I2C_CONSET(x) (x->i2c->CONSET)
bogdanm 15:4892fe388435 50 #define I2C_CONCLR(x) (x->i2c->CONCLR)
bogdanm 15:4892fe388435 51 #define I2C_STAT(x) (x->i2c->STAT)
bogdanm 15:4892fe388435 52 #define I2C_DAT(x) (x->i2c->DAT)
bogdanm 15:4892fe388435 53 #define I2C_SCLL(x, val) (x->i2c->SCLL = val)
bogdanm 15:4892fe388435 54 #define I2C_SCLH(x, val) (x->i2c->SCLH = val)
bogdanm 15:4892fe388435 55
bogdanm 15:4892fe388435 56 static const uint32_t I2C_addr_offset[2][4] = {
bogdanm 15:4892fe388435 57 {0x0C, 0x20, 0x24, 0x28},
bogdanm 15:4892fe388435 58 {0x30, 0x34, 0x38, 0x3C}
bogdanm 15:4892fe388435 59 };
bogdanm 15:4892fe388435 60
bogdanm 15:4892fe388435 61 static inline void i2c_conclr(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) {
bogdanm 15:4892fe388435 62 I2C_CONCLR(obj) = (start << 5)
bogdanm 15:4892fe388435 63 | (stop << 4)
bogdanm 15:4892fe388435 64 | (interrupt << 3)
bogdanm 15:4892fe388435 65 | (acknowledge << 2);
bogdanm 15:4892fe388435 66 }
bogdanm 15:4892fe388435 67
bogdanm 15:4892fe388435 68 static inline void i2c_conset(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) {
bogdanm 15:4892fe388435 69 I2C_CONSET(obj) = (start << 5)
bogdanm 15:4892fe388435 70 | (stop << 4)
bogdanm 15:4892fe388435 71 | (interrupt << 3)
bogdanm 15:4892fe388435 72 | (acknowledge << 2);
bogdanm 15:4892fe388435 73 }
bogdanm 15:4892fe388435 74
bogdanm 15:4892fe388435 75 // Clear the Serial Interrupt (SI)
bogdanm 15:4892fe388435 76 static inline void i2c_clear_SI(i2c_t *obj) {
bogdanm 15:4892fe388435 77 i2c_conclr(obj, 0, 0, 1, 0);
bogdanm 15:4892fe388435 78 }
bogdanm 15:4892fe388435 79
bogdanm 15:4892fe388435 80 static inline int i2c_status(i2c_t *obj) {
bogdanm 15:4892fe388435 81 return I2C_STAT(obj);
bogdanm 15:4892fe388435 82 }
bogdanm 15:4892fe388435 83
bogdanm 15:4892fe388435 84 // Wait until the Serial Interrupt (SI) is set
bogdanm 15:4892fe388435 85 static int i2c_wait_SI(i2c_t *obj) {
bogdanm 15:4892fe388435 86 int timeout = 0;
bogdanm 15:4892fe388435 87 while (!(I2C_CONSET(obj) & (1 << 3))) {
bogdanm 15:4892fe388435 88 timeout++;
bogdanm 15:4892fe388435 89 if (timeout > 100000) return -1;
bogdanm 15:4892fe388435 90 }
bogdanm 15:4892fe388435 91 return 0;
bogdanm 15:4892fe388435 92 }
bogdanm 15:4892fe388435 93
bogdanm 15:4892fe388435 94 static inline void i2c_interface_enable(i2c_t *obj) {
bogdanm 15:4892fe388435 95 I2C_CONSET(obj) = 0x40;
bogdanm 15:4892fe388435 96 }
bogdanm 15:4892fe388435 97
bogdanm 15:4892fe388435 98 static inline void i2c_power_enable(i2c_t *obj) {
bogdanm 15:4892fe388435 99 switch ((int)obj->i2c) {
bogdanm 15:4892fe388435 100 case I2C_0: LPC_SC->PCONP |= 1 << 7; break;
bogdanm 15:4892fe388435 101 case I2C_1: LPC_SC->PCONP |= 1 << 19; break;
bogdanm 15:4892fe388435 102 case I2C_2: LPC_SC->PCONP |= 1 << 26; break;
bogdanm 15:4892fe388435 103 }
bogdanm 15:4892fe388435 104 }
bogdanm 15:4892fe388435 105
bogdanm 15:4892fe388435 106 void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
bogdanm 15:4892fe388435 107 // determine the SPI to use
bogdanm 15:4892fe388435 108 I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
bogdanm 15:4892fe388435 109 I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
bogdanm 15:4892fe388435 110 obj->i2c = (LPC_I2C_TypeDef *)pinmap_merge(i2c_sda, i2c_scl);
bogdanm 15:4892fe388435 111 if ((int)obj->i2c == NC) {
bogdanm 15:4892fe388435 112 error("I2C pin mapping failed");
bogdanm 15:4892fe388435 113 }
bogdanm 15:4892fe388435 114
bogdanm 15:4892fe388435 115 // enable power
bogdanm 15:4892fe388435 116 i2c_power_enable(obj);
bogdanm 15:4892fe388435 117
bogdanm 15:4892fe388435 118 // set default frequency at 100k
bogdanm 15:4892fe388435 119 i2c_frequency(obj, 100000);
bogdanm 15:4892fe388435 120 i2c_conclr(obj, 1, 1, 1, 1);
bogdanm 15:4892fe388435 121 i2c_interface_enable(obj);
bogdanm 15:4892fe388435 122
bogdanm 15:4892fe388435 123 pinmap_pinout(sda, PinMap_I2C_SDA);
bogdanm 15:4892fe388435 124 pinmap_pinout(scl, PinMap_I2C_SCL);
bogdanm 15:4892fe388435 125 }
bogdanm 15:4892fe388435 126
bogdanm 15:4892fe388435 127 inline int i2c_start(i2c_t *obj) {
bogdanm 15:4892fe388435 128 int status = 0;
bogdanm 15:4892fe388435 129 // 8.1 Before master mode can be entered, I2CON must be initialised to:
bogdanm 15:4892fe388435 130 // - I2EN STA STO SI AA - -
bogdanm 15:4892fe388435 131 // - 1 0 0 0 x - -
bogdanm 15:4892fe388435 132 // if AA = 0, it can't enter slave mode
bogdanm 15:4892fe388435 133 i2c_conclr(obj, 1, 1, 1, 1);
bogdanm 15:4892fe388435 134
bogdanm 15:4892fe388435 135 // The master mode may now be entered by setting the STA bit
bogdanm 15:4892fe388435 136 // this will generate a start condition when the bus becomes free
bogdanm 15:4892fe388435 137 i2c_conset(obj, 1, 0, 0, 1);
bogdanm 15:4892fe388435 138
bogdanm 15:4892fe388435 139 i2c_wait_SI(obj);
bogdanm 15:4892fe388435 140 status = i2c_status(obj);
bogdanm 15:4892fe388435 141
bogdanm 15:4892fe388435 142 // Clear start bit now transmitted, and interrupt bit
bogdanm 15:4892fe388435 143 i2c_conclr(obj, 1, 0, 0, 0);
bogdanm 15:4892fe388435 144 return status;
bogdanm 15:4892fe388435 145 }
bogdanm 15:4892fe388435 146
bogdanm 15:4892fe388435 147 inline int i2c_stop(i2c_t *obj) {
bogdanm 15:4892fe388435 148 int timeout = 0;
bogdanm 15:4892fe388435 149
bogdanm 15:4892fe388435 150 // write the stop bit
bogdanm 15:4892fe388435 151 i2c_conset(obj, 0, 1, 0, 0);
bogdanm 15:4892fe388435 152 i2c_clear_SI(obj);
bogdanm 15:4892fe388435 153
bogdanm 15:4892fe388435 154 // wait for STO bit to reset
bogdanm 15:4892fe388435 155 while(I2C_CONSET(obj) & (1 << 4)) {
bogdanm 15:4892fe388435 156 timeout ++;
bogdanm 15:4892fe388435 157 if (timeout > 100000) return 1;
bogdanm 15:4892fe388435 158 }
bogdanm 15:4892fe388435 159
bogdanm 15:4892fe388435 160 return 0;
bogdanm 15:4892fe388435 161 }
bogdanm 15:4892fe388435 162
bogdanm 15:4892fe388435 163
bogdanm 15:4892fe388435 164 static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) {
bogdanm 15:4892fe388435 165 // write the data
bogdanm 15:4892fe388435 166 I2C_DAT(obj) = value;
bogdanm 15:4892fe388435 167
bogdanm 15:4892fe388435 168 // clear SI to init a send
bogdanm 15:4892fe388435 169 i2c_clear_SI(obj);
bogdanm 15:4892fe388435 170
bogdanm 15:4892fe388435 171 // wait and return status
bogdanm 15:4892fe388435 172 i2c_wait_SI(obj);
bogdanm 15:4892fe388435 173 return i2c_status(obj);
bogdanm 15:4892fe388435 174 }
bogdanm 15:4892fe388435 175
bogdanm 15:4892fe388435 176 static inline int i2c_do_read(i2c_t *obj, int last) {
bogdanm 15:4892fe388435 177 // we are in state 0x40 (SLA+R tx'd) or 0x50 (data rx'd and ack)
bogdanm 15:4892fe388435 178 if(last) {
bogdanm 15:4892fe388435 179 i2c_conclr(obj, 0, 0, 0, 1); // send a NOT ACK
bogdanm 15:4892fe388435 180 } else {
bogdanm 15:4892fe388435 181 i2c_conset(obj, 0, 0, 0, 1); // send a ACK
bogdanm 15:4892fe388435 182 }
bogdanm 15:4892fe388435 183
bogdanm 15:4892fe388435 184 // accept byte
bogdanm 15:4892fe388435 185 i2c_clear_SI(obj);
bogdanm 15:4892fe388435 186
bogdanm 15:4892fe388435 187 // wait for it to arrive
bogdanm 15:4892fe388435 188 i2c_wait_SI(obj);
bogdanm 15:4892fe388435 189
bogdanm 15:4892fe388435 190 // return the data
bogdanm 15:4892fe388435 191 return (I2C_DAT(obj) & 0xFF);
bogdanm 15:4892fe388435 192 }
bogdanm 15:4892fe388435 193
bogdanm 15:4892fe388435 194 void i2c_frequency(i2c_t *obj, int hz) {
bogdanm 15:4892fe388435 195 uint32_t PCLK = PeripheralClock;
bogdanm 15:4892fe388435 196 uint32_t pulse = PCLK / (hz * 2);
bogdanm 15:4892fe388435 197
bogdanm 15:4892fe388435 198 // I2C Rate
bogdanm 15:4892fe388435 199 I2C_SCLL(obj, pulse);
bogdanm 15:4892fe388435 200 I2C_SCLH(obj, pulse);
bogdanm 15:4892fe388435 201 }
bogdanm 15:4892fe388435 202
bogdanm 15:4892fe388435 203 // The I2C does a read or a write as a whole operation
bogdanm 15:4892fe388435 204 // There are two types of error conditions it can encounter
bogdanm 15:4892fe388435 205 // 1) it can not obtain the bus
bogdanm 15:4892fe388435 206 // 2) it gets error responses at part of the transmission
bogdanm 15:4892fe388435 207 //
bogdanm 15:4892fe388435 208 // We tackle them as follows:
bogdanm 15:4892fe388435 209 // 1) we retry until we get the bus. we could have a "timeout" if we can not get it
bogdanm 15:4892fe388435 210 // which basically turns it in to a 2)
bogdanm 15:4892fe388435 211 // 2) on error, we use the standard error mechanisms to report/debug
bogdanm 15:4892fe388435 212 //
bogdanm 15:4892fe388435 213 // Therefore an I2C transaction should always complete. If it doesn't it is usually
bogdanm 15:4892fe388435 214 // because something is setup wrong (e.g. wiring), and we don't need to programatically
bogdanm 15:4892fe388435 215 // check for that
bogdanm 15:4892fe388435 216 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
bogdanm 15:4892fe388435 217 int count, status;
bogdanm 15:4892fe388435 218
bogdanm 15:4892fe388435 219 status = i2c_start(obj);
bogdanm 15:4892fe388435 220
bogdanm 15:4892fe388435 221 if ((status != 0x10) && (status != 0x08)) {
bogdanm 15:4892fe388435 222 i2c_stop(obj);
bogdanm 15:4892fe388435 223 return I2C_ERROR_BUS_BUSY;
bogdanm 15:4892fe388435 224 }
bogdanm 15:4892fe388435 225
bogdanm 15:4892fe388435 226 status = i2c_do_write(obj, (address | 0x01), 1);
bogdanm 15:4892fe388435 227 if (status != 0x40) {
bogdanm 15:4892fe388435 228 i2c_stop(obj);
bogdanm 15:4892fe388435 229 return I2C_ERROR_NO_SLAVE;
bogdanm 15:4892fe388435 230 }
bogdanm 15:4892fe388435 231
bogdanm 15:4892fe388435 232 // Read in all except last byte
bogdanm 15:4892fe388435 233 for (count = 0; count < (length - 1); count++) {
bogdanm 15:4892fe388435 234 int value = i2c_do_read(obj, 0);
bogdanm 15:4892fe388435 235 status = i2c_status(obj);
bogdanm 15:4892fe388435 236 if (status != 0x50) {
bogdanm 15:4892fe388435 237 i2c_stop(obj);
bogdanm 15:4892fe388435 238 return count;
bogdanm 15:4892fe388435 239 }
bogdanm 15:4892fe388435 240 data[count] = (char) value;
bogdanm 15:4892fe388435 241 }
bogdanm 15:4892fe388435 242
bogdanm 15:4892fe388435 243 // read in last byte
bogdanm 15:4892fe388435 244 int value = i2c_do_read(obj, 1);
bogdanm 15:4892fe388435 245 status = i2c_status(obj);
bogdanm 15:4892fe388435 246 if (status != 0x58) {
bogdanm 15:4892fe388435 247 i2c_stop(obj);
bogdanm 15:4892fe388435 248 return length - 1;
bogdanm 15:4892fe388435 249 }
bogdanm 15:4892fe388435 250
bogdanm 15:4892fe388435 251 data[count] = (char) value;
bogdanm 15:4892fe388435 252
bogdanm 15:4892fe388435 253 // If not repeated start, send stop.
bogdanm 15:4892fe388435 254 if (stop) {
bogdanm 15:4892fe388435 255 i2c_stop(obj);
bogdanm 15:4892fe388435 256 }
bogdanm 15:4892fe388435 257
bogdanm 15:4892fe388435 258 return length;
bogdanm 15:4892fe388435 259 }
bogdanm 15:4892fe388435 260
bogdanm 15:4892fe388435 261 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
bogdanm 15:4892fe388435 262 int i, status;
bogdanm 15:4892fe388435 263
bogdanm 15:4892fe388435 264 status = i2c_start(obj);
bogdanm 15:4892fe388435 265
bogdanm 15:4892fe388435 266 if ((status != 0x10) && (status != 0x08)) {
bogdanm 15:4892fe388435 267 i2c_stop(obj);
bogdanm 15:4892fe388435 268 return I2C_ERROR_BUS_BUSY;
bogdanm 15:4892fe388435 269 }
bogdanm 15:4892fe388435 270
bogdanm 15:4892fe388435 271 status = i2c_do_write(obj, (address & 0xFE), 1);
bogdanm 15:4892fe388435 272 if (status != 0x18) {
bogdanm 15:4892fe388435 273 i2c_stop(obj);
bogdanm 15:4892fe388435 274 return I2C_ERROR_NO_SLAVE;
bogdanm 15:4892fe388435 275 }
bogdanm 15:4892fe388435 276
bogdanm 15:4892fe388435 277 for (i=0; i<length; i++) {
bogdanm 15:4892fe388435 278 status = i2c_do_write(obj, data[i], 0);
bogdanm 15:4892fe388435 279 if (status != 0x28) {
bogdanm 15:4892fe388435 280 i2c_stop(obj);
bogdanm 15:4892fe388435 281 return i;
bogdanm 15:4892fe388435 282 }
bogdanm 15:4892fe388435 283 }
bogdanm 15:4892fe388435 284
bogdanm 15:4892fe388435 285 // clearing the serial interrupt here might cause an unintended rewrite of the last byte
bogdanm 15:4892fe388435 286 // see also issue report https://mbed.org/users/mbed_official/code/mbed/issues/1
bogdanm 15:4892fe388435 287 // i2c_clear_SI(obj);
bogdanm 15:4892fe388435 288
bogdanm 15:4892fe388435 289 // If not repeated start, send stop.
bogdanm 15:4892fe388435 290 if (stop) {
bogdanm 15:4892fe388435 291 i2c_stop(obj);
bogdanm 15:4892fe388435 292 }
bogdanm 15:4892fe388435 293
bogdanm 15:4892fe388435 294 return length;
bogdanm 15:4892fe388435 295 }
bogdanm 15:4892fe388435 296
bogdanm 15:4892fe388435 297 void i2c_reset(i2c_t *obj) {
bogdanm 15:4892fe388435 298 i2c_stop(obj);
bogdanm 15:4892fe388435 299 }
bogdanm 15:4892fe388435 300
bogdanm 15:4892fe388435 301 int i2c_byte_read(i2c_t *obj, int last) {
bogdanm 15:4892fe388435 302 return (i2c_do_read(obj, last) & 0xFF);
bogdanm 15:4892fe388435 303 }
bogdanm 15:4892fe388435 304
bogdanm 15:4892fe388435 305 int i2c_byte_write(i2c_t *obj, int data) {
bogdanm 15:4892fe388435 306 int ack;
bogdanm 15:4892fe388435 307 int status = i2c_do_write(obj, (data & 0xFF), 0);
bogdanm 15:4892fe388435 308
bogdanm 15:4892fe388435 309 switch(status) {
bogdanm 15:4892fe388435 310 case 0x18: case 0x28: // Master transmit ACKs
bogdanm 15:4892fe388435 311 ack = 1;
bogdanm 15:4892fe388435 312 break;
bogdanm 15:4892fe388435 313
bogdanm 15:4892fe388435 314 case 0x40: // Master receive address transmitted ACK
bogdanm 15:4892fe388435 315 ack = 1;
bogdanm 15:4892fe388435 316 break;
bogdanm 15:4892fe388435 317
bogdanm 15:4892fe388435 318 case 0xB8: // Slave transmit ACK
bogdanm 15:4892fe388435 319 ack = 1;
bogdanm 15:4892fe388435 320 break;
bogdanm 15:4892fe388435 321
bogdanm 15:4892fe388435 322 default:
bogdanm 15:4892fe388435 323 ack = 0;
bogdanm 15:4892fe388435 324 break;
bogdanm 15:4892fe388435 325 }
bogdanm 15:4892fe388435 326
bogdanm 15:4892fe388435 327 return ack;
bogdanm 15:4892fe388435 328 }
bogdanm 15:4892fe388435 329
bogdanm 15:4892fe388435 330 void i2c_slave_mode(i2c_t *obj, int enable_slave) {
bogdanm 15:4892fe388435 331 if (enable_slave != 0) {
bogdanm 15:4892fe388435 332 i2c_conclr(obj, 1, 1, 1, 0);
bogdanm 15:4892fe388435 333 i2c_conset(obj, 0, 0, 0, 1);
bogdanm 15:4892fe388435 334 } else {
bogdanm 15:4892fe388435 335 i2c_conclr(obj, 1, 1, 1, 1);
bogdanm 15:4892fe388435 336 }
bogdanm 15:4892fe388435 337 }
bogdanm 15:4892fe388435 338
bogdanm 15:4892fe388435 339 int i2c_slave_receive(i2c_t *obj) {
bogdanm 15:4892fe388435 340 int status;
bogdanm 15:4892fe388435 341 int retval;
bogdanm 15:4892fe388435 342
bogdanm 15:4892fe388435 343 status = i2c_status(obj);
bogdanm 15:4892fe388435 344 switch(status) {
bogdanm 15:4892fe388435 345 case 0x60: retval = 3; break;
bogdanm 15:4892fe388435 346 case 0x70: retval = 2; break;
bogdanm 15:4892fe388435 347 case 0xA8: retval = 1; break;
bogdanm 15:4892fe388435 348 default : retval = 0; break;
bogdanm 15:4892fe388435 349 }
bogdanm 15:4892fe388435 350
bogdanm 15:4892fe388435 351 return(retval);
bogdanm 15:4892fe388435 352 }
bogdanm 15:4892fe388435 353
bogdanm 15:4892fe388435 354 int i2c_slave_read(i2c_t *obj, char *data, int length) {
bogdanm 15:4892fe388435 355 int count = 0;
bogdanm 15:4892fe388435 356 int status;
bogdanm 15:4892fe388435 357
bogdanm 15:4892fe388435 358 do {
bogdanm 15:4892fe388435 359 i2c_clear_SI(obj);
bogdanm 15:4892fe388435 360 i2c_wait_SI(obj);
bogdanm 15:4892fe388435 361 status = i2c_status(obj);
bogdanm 15:4892fe388435 362 if((status == 0x80) || (status == 0x90)) {
bogdanm 15:4892fe388435 363 data[count] = I2C_DAT(obj) & 0xFF;
bogdanm 15:4892fe388435 364 }
bogdanm 15:4892fe388435 365 count++;
bogdanm 15:4892fe388435 366 } while (((status == 0x80) || (status == 0x90) ||
bogdanm 15:4892fe388435 367 (status == 0x060) || (status == 0x70)) && (count < length));
bogdanm 15:4892fe388435 368
bogdanm 15:4892fe388435 369 if(status != 0xA0) {
bogdanm 15:4892fe388435 370 i2c_stop(obj);
bogdanm 15:4892fe388435 371 }
bogdanm 15:4892fe388435 372
bogdanm 15:4892fe388435 373 i2c_clear_SI(obj);
bogdanm 15:4892fe388435 374
bogdanm 15:4892fe388435 375 return count;
bogdanm 15:4892fe388435 376 }
bogdanm 15:4892fe388435 377
bogdanm 15:4892fe388435 378 int i2c_slave_write(i2c_t *obj, const char *data, int length) {
bogdanm 15:4892fe388435 379 int count = 0;
bogdanm 15:4892fe388435 380 int status;
bogdanm 15:4892fe388435 381
bogdanm 15:4892fe388435 382 if(length <= 0) {
bogdanm 15:4892fe388435 383 return(0);
bogdanm 15:4892fe388435 384 }
bogdanm 15:4892fe388435 385
bogdanm 15:4892fe388435 386 do {
bogdanm 15:4892fe388435 387 status = i2c_do_write(obj, data[count], 0);
bogdanm 15:4892fe388435 388 count++;
bogdanm 15:4892fe388435 389 } while ((count < length) && (status == 0xB8));
bogdanm 15:4892fe388435 390
bogdanm 15:4892fe388435 391 if((status != 0xC0) && (status != 0xC8)) {
bogdanm 15:4892fe388435 392 i2c_stop(obj);
bogdanm 15:4892fe388435 393 }
bogdanm 15:4892fe388435 394
bogdanm 15:4892fe388435 395 i2c_clear_SI(obj);
bogdanm 15:4892fe388435 396
bogdanm 15:4892fe388435 397 return(count);
bogdanm 15:4892fe388435 398 }
bogdanm 15:4892fe388435 399
bogdanm 15:4892fe388435 400 void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
bogdanm 15:4892fe388435 401 uint32_t addr;
bogdanm 15:4892fe388435 402
bogdanm 15:4892fe388435 403 if ((idx >= 0) && (idx <= 3)) {
bogdanm 15:4892fe388435 404 addr = ((uint32_t)obj->i2c) + I2C_addr_offset[0][idx];
bogdanm 15:4892fe388435 405 *((uint32_t *) addr) = address & 0xFF;
bogdanm 15:4892fe388435 406 addr = ((uint32_t)obj->i2c) + I2C_addr_offset[1][idx];
bogdanm 15:4892fe388435 407 *((uint32_t *) addr) = mask & 0xFE;
bogdanm 15:4892fe388435 408 }
bogdanm 15:4892fe388435 409 }