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:
mbed_official
Date:
Tue Dec 16 08:15:08 2014 +0000
Revision:
440:8a0b45cd594f
Parent:
227:7bd0639b8911
Synchronized with git revision 67fbbf0b635d0c0d93fbe433306c537c2ad206aa

Full URL: https://github.com/mbedmicro/mbed/commit/67fbbf0b635d0c0d93fbe433306c537c2ad206aa/

Targets: nrf51 - updating app_timer.c from Norid'c SDKv7.1.0

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 */
mbed_official 227:7bd0639b8911 16 #include "mbed_assert.h"
bogdanm 15:4892fe388435 17 #include "i2c_api.h"
bogdanm 15:4892fe388435 18 #include "cmsis.h"
bogdanm 15:4892fe388435 19 #include "pinmap.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);
mbed_official 227:7bd0639b8911 111 MBED_ASSERT((int)obj->i2c != NC);
bogdanm 15:4892fe388435 112
bogdanm 15:4892fe388435 113 // enable power
bogdanm 15:4892fe388435 114 i2c_power_enable(obj);
bogdanm 15:4892fe388435 115
bogdanm 15:4892fe388435 116 // set default frequency at 100k
bogdanm 15:4892fe388435 117 i2c_frequency(obj, 100000);
bogdanm 15:4892fe388435 118 i2c_conclr(obj, 1, 1, 1, 1);
bogdanm 15:4892fe388435 119 i2c_interface_enable(obj);
bogdanm 15:4892fe388435 120
bogdanm 15:4892fe388435 121 pinmap_pinout(sda, PinMap_I2C_SDA);
bogdanm 15:4892fe388435 122 pinmap_pinout(scl, PinMap_I2C_SCL);
mbed_official 34:a3c7023e45de 123
mbed_official 34:a3c7023e45de 124 // OpenDrain must explicitly be enabled for p0.0 and p0.1
mbed_official 34:a3c7023e45de 125 if (sda == P0_0) {
mbed_official 34:a3c7023e45de 126 pin_mode(sda, OpenDrain);
mbed_official 34:a3c7023e45de 127 }
mbed_official 34:a3c7023e45de 128 if (scl == P0_1) {
mbed_official 34:a3c7023e45de 129 pin_mode(scl, OpenDrain);
mbed_official 34:a3c7023e45de 130 }
mbed_official 34:a3c7023e45de 131
bogdanm 15:4892fe388435 132 }
bogdanm 15:4892fe388435 133
bogdanm 15:4892fe388435 134 inline int i2c_start(i2c_t *obj) {
bogdanm 15:4892fe388435 135 int status = 0;
bogdanm 15:4892fe388435 136 // 8.1 Before master mode can be entered, I2CON must be initialised to:
bogdanm 15:4892fe388435 137 // - I2EN STA STO SI AA - -
bogdanm 15:4892fe388435 138 // - 1 0 0 0 x - -
bogdanm 15:4892fe388435 139 // if AA = 0, it can't enter slave mode
bogdanm 15:4892fe388435 140 i2c_conclr(obj, 1, 1, 1, 1);
bogdanm 15:4892fe388435 141
bogdanm 15:4892fe388435 142 // The master mode may now be entered by setting the STA bit
bogdanm 15:4892fe388435 143 // this will generate a start condition when the bus becomes free
bogdanm 15:4892fe388435 144 i2c_conset(obj, 1, 0, 0, 1);
bogdanm 15:4892fe388435 145
bogdanm 15:4892fe388435 146 i2c_wait_SI(obj);
bogdanm 15:4892fe388435 147 status = i2c_status(obj);
bogdanm 15:4892fe388435 148
bogdanm 15:4892fe388435 149 // Clear start bit now transmitted, and interrupt bit
bogdanm 15:4892fe388435 150 i2c_conclr(obj, 1, 0, 0, 0);
bogdanm 15:4892fe388435 151 return status;
bogdanm 15:4892fe388435 152 }
bogdanm 15:4892fe388435 153
bogdanm 15:4892fe388435 154 inline int i2c_stop(i2c_t *obj) {
bogdanm 15:4892fe388435 155 int timeout = 0;
bogdanm 15:4892fe388435 156
bogdanm 15:4892fe388435 157 // write the stop bit
bogdanm 15:4892fe388435 158 i2c_conset(obj, 0, 1, 0, 0);
bogdanm 15:4892fe388435 159 i2c_clear_SI(obj);
bogdanm 15:4892fe388435 160
bogdanm 15:4892fe388435 161 // wait for STO bit to reset
bogdanm 15:4892fe388435 162 while(I2C_CONSET(obj) & (1 << 4)) {
bogdanm 15:4892fe388435 163 timeout ++;
bogdanm 15:4892fe388435 164 if (timeout > 100000) return 1;
bogdanm 15:4892fe388435 165 }
bogdanm 15:4892fe388435 166
bogdanm 15:4892fe388435 167 return 0;
bogdanm 15:4892fe388435 168 }
bogdanm 15:4892fe388435 169
bogdanm 15:4892fe388435 170
bogdanm 15:4892fe388435 171 static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) {
bogdanm 15:4892fe388435 172 // write the data
bogdanm 15:4892fe388435 173 I2C_DAT(obj) = value;
bogdanm 15:4892fe388435 174
bogdanm 15:4892fe388435 175 // clear SI to init a send
bogdanm 15:4892fe388435 176 i2c_clear_SI(obj);
bogdanm 15:4892fe388435 177
bogdanm 15:4892fe388435 178 // wait and return status
bogdanm 15:4892fe388435 179 i2c_wait_SI(obj);
bogdanm 15:4892fe388435 180 return i2c_status(obj);
bogdanm 15:4892fe388435 181 }
bogdanm 15:4892fe388435 182
bogdanm 15:4892fe388435 183 static inline int i2c_do_read(i2c_t *obj, int last) {
bogdanm 15:4892fe388435 184 // we are in state 0x40 (SLA+R tx'd) or 0x50 (data rx'd and ack)
bogdanm 15:4892fe388435 185 if(last) {
bogdanm 15:4892fe388435 186 i2c_conclr(obj, 0, 0, 0, 1); // send a NOT ACK
bogdanm 15:4892fe388435 187 } else {
bogdanm 15:4892fe388435 188 i2c_conset(obj, 0, 0, 0, 1); // send a ACK
bogdanm 15:4892fe388435 189 }
bogdanm 15:4892fe388435 190
bogdanm 15:4892fe388435 191 // accept byte
bogdanm 15:4892fe388435 192 i2c_clear_SI(obj);
bogdanm 15:4892fe388435 193
bogdanm 15:4892fe388435 194 // wait for it to arrive
bogdanm 15:4892fe388435 195 i2c_wait_SI(obj);
bogdanm 15:4892fe388435 196
bogdanm 15:4892fe388435 197 // return the data
bogdanm 15:4892fe388435 198 return (I2C_DAT(obj) & 0xFF);
bogdanm 15:4892fe388435 199 }
bogdanm 15:4892fe388435 200
bogdanm 15:4892fe388435 201 void i2c_frequency(i2c_t *obj, int hz) {
bogdanm 15:4892fe388435 202 uint32_t PCLK = PeripheralClock;
bogdanm 15:4892fe388435 203 uint32_t pulse = PCLK / (hz * 2);
bogdanm 15:4892fe388435 204
bogdanm 15:4892fe388435 205 // I2C Rate
bogdanm 15:4892fe388435 206 I2C_SCLL(obj, pulse);
bogdanm 15:4892fe388435 207 I2C_SCLH(obj, pulse);
bogdanm 15:4892fe388435 208 }
bogdanm 15:4892fe388435 209
bogdanm 15:4892fe388435 210 // The I2C does a read or a write as a whole operation
bogdanm 15:4892fe388435 211 // There are two types of error conditions it can encounter
bogdanm 15:4892fe388435 212 // 1) it can not obtain the bus
bogdanm 15:4892fe388435 213 // 2) it gets error responses at part of the transmission
bogdanm 15:4892fe388435 214 //
bogdanm 15:4892fe388435 215 // We tackle them as follows:
bogdanm 15:4892fe388435 216 // 1) we retry until we get the bus. we could have a "timeout" if we can not get it
bogdanm 15:4892fe388435 217 // which basically turns it in to a 2)
bogdanm 15:4892fe388435 218 // 2) on error, we use the standard error mechanisms to report/debug
bogdanm 15:4892fe388435 219 //
bogdanm 15:4892fe388435 220 // Therefore an I2C transaction should always complete. If it doesn't it is usually
bogdanm 15:4892fe388435 221 // because something is setup wrong (e.g. wiring), and we don't need to programatically
bogdanm 15:4892fe388435 222 // check for that
bogdanm 15:4892fe388435 223 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
bogdanm 15:4892fe388435 224 int count, status;
bogdanm 15:4892fe388435 225
bogdanm 15:4892fe388435 226 status = i2c_start(obj);
bogdanm 15:4892fe388435 227
bogdanm 15:4892fe388435 228 if ((status != 0x10) && (status != 0x08)) {
bogdanm 15:4892fe388435 229 i2c_stop(obj);
bogdanm 15:4892fe388435 230 return I2C_ERROR_BUS_BUSY;
bogdanm 15:4892fe388435 231 }
bogdanm 15:4892fe388435 232
bogdanm 15:4892fe388435 233 status = i2c_do_write(obj, (address | 0x01), 1);
bogdanm 15:4892fe388435 234 if (status != 0x40) {
bogdanm 15:4892fe388435 235 i2c_stop(obj);
bogdanm 15:4892fe388435 236 return I2C_ERROR_NO_SLAVE;
bogdanm 15:4892fe388435 237 }
bogdanm 15:4892fe388435 238
bogdanm 15:4892fe388435 239 // Read in all except last byte
bogdanm 15:4892fe388435 240 for (count = 0; count < (length - 1); count++) {
bogdanm 15:4892fe388435 241 int value = i2c_do_read(obj, 0);
bogdanm 15:4892fe388435 242 status = i2c_status(obj);
bogdanm 15:4892fe388435 243 if (status != 0x50) {
bogdanm 15:4892fe388435 244 i2c_stop(obj);
bogdanm 15:4892fe388435 245 return count;
bogdanm 15:4892fe388435 246 }
bogdanm 15:4892fe388435 247 data[count] = (char) value;
bogdanm 15:4892fe388435 248 }
bogdanm 15:4892fe388435 249
bogdanm 15:4892fe388435 250 // read in last byte
bogdanm 15:4892fe388435 251 int value = i2c_do_read(obj, 1);
bogdanm 15:4892fe388435 252 status = i2c_status(obj);
bogdanm 15:4892fe388435 253 if (status != 0x58) {
bogdanm 15:4892fe388435 254 i2c_stop(obj);
bogdanm 15:4892fe388435 255 return length - 1;
bogdanm 15:4892fe388435 256 }
bogdanm 15:4892fe388435 257
bogdanm 15:4892fe388435 258 data[count] = (char) value;
bogdanm 15:4892fe388435 259
bogdanm 15:4892fe388435 260 // If not repeated start, send stop.
bogdanm 15:4892fe388435 261 if (stop) {
bogdanm 15:4892fe388435 262 i2c_stop(obj);
bogdanm 15:4892fe388435 263 }
bogdanm 15:4892fe388435 264
bogdanm 15:4892fe388435 265 return length;
bogdanm 15:4892fe388435 266 }
bogdanm 15:4892fe388435 267
bogdanm 15:4892fe388435 268 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
bogdanm 15:4892fe388435 269 int i, status;
bogdanm 15:4892fe388435 270
bogdanm 15:4892fe388435 271 status = i2c_start(obj);
bogdanm 15:4892fe388435 272
bogdanm 15:4892fe388435 273 if ((status != 0x10) && (status != 0x08)) {
bogdanm 15:4892fe388435 274 i2c_stop(obj);
bogdanm 15:4892fe388435 275 return I2C_ERROR_BUS_BUSY;
bogdanm 15:4892fe388435 276 }
bogdanm 15:4892fe388435 277
bogdanm 15:4892fe388435 278 status = i2c_do_write(obj, (address & 0xFE), 1);
bogdanm 15:4892fe388435 279 if (status != 0x18) {
bogdanm 15:4892fe388435 280 i2c_stop(obj);
bogdanm 15:4892fe388435 281 return I2C_ERROR_NO_SLAVE;
bogdanm 15:4892fe388435 282 }
bogdanm 15:4892fe388435 283
bogdanm 15:4892fe388435 284 for (i=0; i<length; i++) {
bogdanm 15:4892fe388435 285 status = i2c_do_write(obj, data[i], 0);
bogdanm 15:4892fe388435 286 if (status != 0x28) {
bogdanm 15:4892fe388435 287 i2c_stop(obj);
bogdanm 15:4892fe388435 288 return i;
bogdanm 15:4892fe388435 289 }
bogdanm 15:4892fe388435 290 }
bogdanm 15:4892fe388435 291
bogdanm 15:4892fe388435 292 // clearing the serial interrupt here might cause an unintended rewrite of the last byte
bogdanm 15:4892fe388435 293 // see also issue report https://mbed.org/users/mbed_official/code/mbed/issues/1
bogdanm 15:4892fe388435 294 // i2c_clear_SI(obj);
bogdanm 15:4892fe388435 295
bogdanm 15:4892fe388435 296 // If not repeated start, send stop.
bogdanm 15:4892fe388435 297 if (stop) {
bogdanm 15:4892fe388435 298 i2c_stop(obj);
bogdanm 15:4892fe388435 299 }
bogdanm 15:4892fe388435 300
bogdanm 15:4892fe388435 301 return length;
bogdanm 15:4892fe388435 302 }
bogdanm 15:4892fe388435 303
bogdanm 15:4892fe388435 304 void i2c_reset(i2c_t *obj) {
bogdanm 15:4892fe388435 305 i2c_stop(obj);
bogdanm 15:4892fe388435 306 }
bogdanm 15:4892fe388435 307
bogdanm 15:4892fe388435 308 int i2c_byte_read(i2c_t *obj, int last) {
bogdanm 15:4892fe388435 309 return (i2c_do_read(obj, last) & 0xFF);
bogdanm 15:4892fe388435 310 }
bogdanm 15:4892fe388435 311
bogdanm 15:4892fe388435 312 int i2c_byte_write(i2c_t *obj, int data) {
bogdanm 15:4892fe388435 313 int ack;
bogdanm 15:4892fe388435 314 int status = i2c_do_write(obj, (data & 0xFF), 0);
bogdanm 15:4892fe388435 315
bogdanm 15:4892fe388435 316 switch(status) {
bogdanm 15:4892fe388435 317 case 0x18: case 0x28: // Master transmit ACKs
bogdanm 15:4892fe388435 318 ack = 1;
bogdanm 15:4892fe388435 319 break;
bogdanm 15:4892fe388435 320
bogdanm 15:4892fe388435 321 case 0x40: // Master receive address transmitted ACK
bogdanm 15:4892fe388435 322 ack = 1;
bogdanm 15:4892fe388435 323 break;
bogdanm 15:4892fe388435 324
bogdanm 15:4892fe388435 325 case 0xB8: // Slave transmit ACK
bogdanm 15:4892fe388435 326 ack = 1;
bogdanm 15:4892fe388435 327 break;
bogdanm 15:4892fe388435 328
bogdanm 15:4892fe388435 329 default:
bogdanm 15:4892fe388435 330 ack = 0;
bogdanm 15:4892fe388435 331 break;
bogdanm 15:4892fe388435 332 }
bogdanm 15:4892fe388435 333
bogdanm 15:4892fe388435 334 return ack;
bogdanm 15:4892fe388435 335 }
bogdanm 15:4892fe388435 336
bogdanm 15:4892fe388435 337 void i2c_slave_mode(i2c_t *obj, int enable_slave) {
bogdanm 15:4892fe388435 338 if (enable_slave != 0) {
bogdanm 15:4892fe388435 339 i2c_conclr(obj, 1, 1, 1, 0);
bogdanm 15:4892fe388435 340 i2c_conset(obj, 0, 0, 0, 1);
bogdanm 15:4892fe388435 341 } else {
bogdanm 15:4892fe388435 342 i2c_conclr(obj, 1, 1, 1, 1);
bogdanm 15:4892fe388435 343 }
bogdanm 15:4892fe388435 344 }
bogdanm 15:4892fe388435 345
bogdanm 15:4892fe388435 346 int i2c_slave_receive(i2c_t *obj) {
bogdanm 15:4892fe388435 347 int status;
bogdanm 15:4892fe388435 348 int retval;
bogdanm 15:4892fe388435 349
bogdanm 15:4892fe388435 350 status = i2c_status(obj);
bogdanm 15:4892fe388435 351 switch(status) {
bogdanm 15:4892fe388435 352 case 0x60: retval = 3; break;
bogdanm 15:4892fe388435 353 case 0x70: retval = 2; break;
bogdanm 15:4892fe388435 354 case 0xA8: retval = 1; break;
bogdanm 15:4892fe388435 355 default : retval = 0; break;
bogdanm 15:4892fe388435 356 }
bogdanm 15:4892fe388435 357
bogdanm 15:4892fe388435 358 return(retval);
bogdanm 15:4892fe388435 359 }
bogdanm 15:4892fe388435 360
bogdanm 15:4892fe388435 361 int i2c_slave_read(i2c_t *obj, char *data, int length) {
bogdanm 15:4892fe388435 362 int count = 0;
bogdanm 15:4892fe388435 363 int status;
bogdanm 15:4892fe388435 364
bogdanm 15:4892fe388435 365 do {
bogdanm 15:4892fe388435 366 i2c_clear_SI(obj);
bogdanm 15:4892fe388435 367 i2c_wait_SI(obj);
bogdanm 15:4892fe388435 368 status = i2c_status(obj);
bogdanm 15:4892fe388435 369 if((status == 0x80) || (status == 0x90)) {
bogdanm 15:4892fe388435 370 data[count] = I2C_DAT(obj) & 0xFF;
bogdanm 15:4892fe388435 371 }
bogdanm 15:4892fe388435 372 count++;
bogdanm 15:4892fe388435 373 } while (((status == 0x80) || (status == 0x90) ||
bogdanm 15:4892fe388435 374 (status == 0x060) || (status == 0x70)) && (count < length));
bogdanm 15:4892fe388435 375
bogdanm 15:4892fe388435 376 if(status != 0xA0) {
bogdanm 15:4892fe388435 377 i2c_stop(obj);
bogdanm 15:4892fe388435 378 }
bogdanm 15:4892fe388435 379
bogdanm 15:4892fe388435 380 i2c_clear_SI(obj);
bogdanm 15:4892fe388435 381
bogdanm 15:4892fe388435 382 return count;
bogdanm 15:4892fe388435 383 }
bogdanm 15:4892fe388435 384
bogdanm 15:4892fe388435 385 int i2c_slave_write(i2c_t *obj, const char *data, int length) {
bogdanm 15:4892fe388435 386 int count = 0;
bogdanm 15:4892fe388435 387 int status;
bogdanm 15:4892fe388435 388
bogdanm 15:4892fe388435 389 if(length <= 0) {
bogdanm 15:4892fe388435 390 return(0);
bogdanm 15:4892fe388435 391 }
bogdanm 15:4892fe388435 392
bogdanm 15:4892fe388435 393 do {
bogdanm 15:4892fe388435 394 status = i2c_do_write(obj, data[count], 0);
bogdanm 15:4892fe388435 395 count++;
bogdanm 15:4892fe388435 396 } while ((count < length) && (status == 0xB8));
bogdanm 15:4892fe388435 397
bogdanm 15:4892fe388435 398 if((status != 0xC0) && (status != 0xC8)) {
bogdanm 15:4892fe388435 399 i2c_stop(obj);
bogdanm 15:4892fe388435 400 }
bogdanm 15:4892fe388435 401
bogdanm 15:4892fe388435 402 i2c_clear_SI(obj);
bogdanm 15:4892fe388435 403
bogdanm 15:4892fe388435 404 return(count);
bogdanm 15:4892fe388435 405 }
bogdanm 15:4892fe388435 406
bogdanm 15:4892fe388435 407 void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
bogdanm 15:4892fe388435 408 uint32_t addr;
bogdanm 15:4892fe388435 409
bogdanm 15:4892fe388435 410 if ((idx >= 0) && (idx <= 3)) {
bogdanm 15:4892fe388435 411 addr = ((uint32_t)obj->i2c) + I2C_addr_offset[0][idx];
bogdanm 15:4892fe388435 412 *((uint32_t *) addr) = address & 0xFF;
bogdanm 15:4892fe388435 413 addr = ((uint32_t)obj->i2c) + I2C_addr_offset[1][idx];
bogdanm 15:4892fe388435 414 *((uint32_t *) addr) = mask & 0xFE;
bogdanm 15:4892fe388435 415 }
bogdanm 15:4892fe388435 416 }