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
Parent:
13:0645d8841f51
Child:
18:692be3d4e4cc
Added LPC4088 target and interrupt chaining code

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bogdanm 13:0645d8841f51 1 /* mbed Microcontroller Library
bogdanm 13:0645d8841f51 2 * Copyright (c) 2006-2013 ARM Limited
bogdanm 13:0645d8841f51 3 *
bogdanm 13:0645d8841f51 4 * Licensed under the Apache License, Version 2.0 (the "License");
bogdanm 13:0645d8841f51 5 * you may not use this file except in compliance with the License.
bogdanm 13:0645d8841f51 6 * You may obtain a copy of the License at
bogdanm 13:0645d8841f51 7 *
bogdanm 13:0645d8841f51 8 * http://www.apache.org/licenses/LICENSE-2.0
bogdanm 13:0645d8841f51 9 *
bogdanm 13:0645d8841f51 10 * Unless required by applicable law or agreed to in writing, software
bogdanm 13:0645d8841f51 11 * distributed under the License is distributed on an "AS IS" BASIS,
bogdanm 13:0645d8841f51 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
bogdanm 13:0645d8841f51 13 * See the License for the specific language governing permissions and
bogdanm 13:0645d8841f51 14 * limitations under the License.
bogdanm 13:0645d8841f51 15 */
bogdanm 13:0645d8841f51 16 #include "i2c_api.h"
bogdanm 13:0645d8841f51 17
bogdanm 13:0645d8841f51 18 #include "cmsis.h"
bogdanm 13:0645d8841f51 19 #include "pinmap.h"
bogdanm 13:0645d8841f51 20 #include "error.h"
bogdanm 13:0645d8841f51 21
bogdanm 13:0645d8841f51 22 static const PinMap PinMap_I2C_SDA[] = {
bogdanm 13:0645d8841f51 23 {PTE25, I2C_0, 5},
bogdanm 13:0645d8841f51 24 {PTC9, I2C_0, 2},
bogdanm 13:0645d8841f51 25 {PTE0, I2C_1, 6},
bogdanm 13:0645d8841f51 26 {PTB1, I2C_0, 2},
bogdanm 13:0645d8841f51 27 {PTB3, I2C_0, 2},
bogdanm 15:4892fe388435 28 {PTC11, I2C_1, 2},
bogdanm 15:4892fe388435 29 {PTC2, I2C_1, 2},
bogdanm 15:4892fe388435 30 {PTA4, I2C_1, 2},
bogdanm 13:0645d8841f51 31 {NC , NC , 0}
bogdanm 13:0645d8841f51 32 };
bogdanm 13:0645d8841f51 33
bogdanm 13:0645d8841f51 34 static const PinMap PinMap_I2C_SCL[] = {
bogdanm 13:0645d8841f51 35 {PTE24, I2C_0, 5},
bogdanm 13:0645d8841f51 36 {PTC8, I2C_0, 2},
bogdanm 13:0645d8841f51 37 {PTE1, I2C_1, 6},
bogdanm 13:0645d8841f51 38 {PTB0, I2C_0, 2},
bogdanm 13:0645d8841f51 39 {PTB2, I2C_0, 2},
bogdanm 15:4892fe388435 40 {PTC10, I2C_1, 2},
bogdanm 15:4892fe388435 41 {PTC1, I2C_1, 2},
bogdanm 13:0645d8841f51 42 {NC , NC, 0}
bogdanm 13:0645d8841f51 43 };
bogdanm 13:0645d8841f51 44
bogdanm 13:0645d8841f51 45 static const uint16_t ICR[0x40] = {
bogdanm 13:0645d8841f51 46 20, 22, 24, 26, 28,
bogdanm 13:0645d8841f51 47 30, 34, 40, 28, 32,
bogdanm 13:0645d8841f51 48 36, 40, 44, 48, 56,
bogdanm 13:0645d8841f51 49 68, 48, 56, 64, 72,
bogdanm 13:0645d8841f51 50 80, 88, 104, 128, 80,
bogdanm 13:0645d8841f51 51 96, 112, 128, 144, 160,
bogdanm 13:0645d8841f51 52 192, 240, 160, 192, 224,
bogdanm 13:0645d8841f51 53 256, 288, 320, 384, 480,
bogdanm 13:0645d8841f51 54 320, 384, 448, 512, 576,
bogdanm 13:0645d8841f51 55 640, 768, 960, 640, 768,
bogdanm 13:0645d8841f51 56 896, 1024, 1152, 1280, 1536,
bogdanm 13:0645d8841f51 57 1920, 1280, 1536, 1792, 2048,
bogdanm 13:0645d8841f51 58 2304, 2560, 3072, 3840
bogdanm 13:0645d8841f51 59 };
bogdanm 13:0645d8841f51 60
bogdanm 13:0645d8841f51 61 static uint8_t first_read;
bogdanm 13:0645d8841f51 62
bogdanm 13:0645d8841f51 63
bogdanm 13:0645d8841f51 64 void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
bogdanm 13:0645d8841f51 65 // determine the I2C to use
bogdanm 13:0645d8841f51 66 I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
bogdanm 13:0645d8841f51 67 I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
bogdanm 13:0645d8841f51 68 obj->i2c = (I2C_Type*)pinmap_merge(i2c_sda, i2c_scl);
bogdanm 13:0645d8841f51 69 if ((int)obj->i2c == NC) {
bogdanm 13:0645d8841f51 70 error("I2C pin mapping failed");
bogdanm 13:0645d8841f51 71 }
bogdanm 13:0645d8841f51 72
bogdanm 13:0645d8841f51 73 // enable power
bogdanm 13:0645d8841f51 74 switch ((int)obj->i2c) {
bogdanm 13:0645d8841f51 75 case I2C_0: SIM->SCGC5 |= 1 << 13; SIM->SCGC4 |= 1 << 6; break;
bogdanm 13:0645d8841f51 76 case I2C_1: SIM->SCGC5 |= 1 << 11; SIM->SCGC4 |= 1 << 7; break;
bogdanm 13:0645d8841f51 77 }
bogdanm 13:0645d8841f51 78
bogdanm 13:0645d8841f51 79 // set default frequency at 100k
bogdanm 13:0645d8841f51 80 i2c_frequency(obj, 100000);
bogdanm 13:0645d8841f51 81
bogdanm 13:0645d8841f51 82 // enable I2C interface
bogdanm 13:0645d8841f51 83 obj->i2c->C1 |= 0x80;
bogdanm 13:0645d8841f51 84
bogdanm 13:0645d8841f51 85 pinmap_pinout(sda, PinMap_I2C_SDA);
bogdanm 13:0645d8841f51 86 pinmap_pinout(scl, PinMap_I2C_SCL);
bogdanm 13:0645d8841f51 87
bogdanm 13:0645d8841f51 88 first_read = 1;
bogdanm 13:0645d8841f51 89 }
bogdanm 13:0645d8841f51 90
bogdanm 13:0645d8841f51 91 int i2c_start(i2c_t *obj) {
bogdanm 15:4892fe388435 92 uint8_t temp;
bogdanm 15:4892fe388435 93 volatile int i;
bogdanm 13:0645d8841f51 94 // if we are in the middle of a transaction
bogdanm 13:0645d8841f51 95 // activate the repeat_start flag
bogdanm 13:0645d8841f51 96 if (obj->i2c->S & I2C_S_BUSY_MASK) {
bogdanm 15:4892fe388435 97 // KL25Z errata sheet: repeat start cannot be generated if the
bogdanm 15:4892fe388435 98 // I2Cx_F[MULT] field is set to a non-zero value
bogdanm 15:4892fe388435 99 temp = obj->i2c->F >> 6;
bogdanm 15:4892fe388435 100 obj->i2c->F &= 0x3F;
bogdanm 13:0645d8841f51 101 obj->i2c->C1 |= 0x04;
bogdanm 15:4892fe388435 102 for (i = 0; i < 100; i ++) __NOP();
bogdanm 15:4892fe388435 103 obj->i2c->F |= temp << 6;
bogdanm 13:0645d8841f51 104 } else {
bogdanm 13:0645d8841f51 105 obj->i2c->C1 |= I2C_C1_MST_MASK;
bogdanm 13:0645d8841f51 106 obj->i2c->C1 |= I2C_C1_TX_MASK;
bogdanm 13:0645d8841f51 107 }
bogdanm 13:0645d8841f51 108 first_read = 1;
bogdanm 13:0645d8841f51 109 return 0;
bogdanm 13:0645d8841f51 110 }
bogdanm 13:0645d8841f51 111
bogdanm 13:0645d8841f51 112 int i2c_stop(i2c_t *obj) {
bogdanm 13:0645d8841f51 113 volatile uint32_t n = 0;
bogdanm 13:0645d8841f51 114 obj->i2c->C1 &= ~I2C_C1_MST_MASK;
bogdanm 13:0645d8841f51 115 obj->i2c->C1 &= ~I2C_C1_TX_MASK;
bogdanm 13:0645d8841f51 116
bogdanm 13:0645d8841f51 117 // It seems that there are timing problems
bogdanm 13:0645d8841f51 118 // when there is no waiting time after a STOP.
bogdanm 13:0645d8841f51 119 // This wait is also included on the samples
bogdanm 13:0645d8841f51 120 // code provided with the freedom board
bogdanm 13:0645d8841f51 121 for (n = 0; n < 100; n++) __NOP();
bogdanm 13:0645d8841f51 122 first_read = 1;
bogdanm 13:0645d8841f51 123 return 0;
bogdanm 13:0645d8841f51 124 }
bogdanm 13:0645d8841f51 125
bogdanm 13:0645d8841f51 126 static int timeout_status_poll(i2c_t *obj, uint32_t mask) {
bogdanm 13:0645d8841f51 127 uint32_t i, timeout = 1000;
bogdanm 13:0645d8841f51 128
bogdanm 13:0645d8841f51 129 for (i = 0; i < timeout; i++) {
bogdanm 13:0645d8841f51 130 if (obj->i2c->S & mask)
bogdanm 13:0645d8841f51 131 return 0;
bogdanm 13:0645d8841f51 132 }
bogdanm 13:0645d8841f51 133
bogdanm 13:0645d8841f51 134 return 1;
bogdanm 13:0645d8841f51 135 }
bogdanm 13:0645d8841f51 136
bogdanm 13:0645d8841f51 137 // this function waits the end of a tx transfer and return the status of the transaction:
bogdanm 13:0645d8841f51 138 // 0: OK ack received
bogdanm 13:0645d8841f51 139 // 1: OK ack not received
bogdanm 13:0645d8841f51 140 // 2: failure
bogdanm 13:0645d8841f51 141 static int i2c_wait_end_tx_transfer(i2c_t *obj) {
bogdanm 13:0645d8841f51 142
bogdanm 13:0645d8841f51 143 // wait for the interrupt flag
bogdanm 13:0645d8841f51 144 if (timeout_status_poll(obj, I2C_S_IICIF_MASK)) {
bogdanm 13:0645d8841f51 145 return 2;
bogdanm 13:0645d8841f51 146 }
bogdanm 13:0645d8841f51 147
bogdanm 13:0645d8841f51 148 obj->i2c->S |= I2C_S_IICIF_MASK;
bogdanm 13:0645d8841f51 149
bogdanm 13:0645d8841f51 150 // wait transfer complete
bogdanm 13:0645d8841f51 151 if (timeout_status_poll(obj, I2C_S_TCF_MASK)) {
bogdanm 13:0645d8841f51 152 return 2;
bogdanm 13:0645d8841f51 153 }
bogdanm 13:0645d8841f51 154
bogdanm 13:0645d8841f51 155 // check if we received the ACK or not
bogdanm 13:0645d8841f51 156 return obj->i2c->S & I2C_S_RXAK_MASK ? 1 : 0;
bogdanm 13:0645d8841f51 157 }
bogdanm 13:0645d8841f51 158
bogdanm 13:0645d8841f51 159 // this function waits the end of a rx transfer and return the status of the transaction:
bogdanm 13:0645d8841f51 160 // 0: OK
bogdanm 13:0645d8841f51 161 // 1: failure
bogdanm 13:0645d8841f51 162 static int i2c_wait_end_rx_transfer(i2c_t *obj) {
bogdanm 13:0645d8841f51 163 // wait for the end of the rx transfer
bogdanm 13:0645d8841f51 164 if (timeout_status_poll(obj, I2C_S_IICIF_MASK)) {
bogdanm 13:0645d8841f51 165 return 1;
bogdanm 13:0645d8841f51 166 }
bogdanm 13:0645d8841f51 167
bogdanm 13:0645d8841f51 168 obj->i2c->S |= I2C_S_IICIF_MASK;
bogdanm 13:0645d8841f51 169
bogdanm 13:0645d8841f51 170 return 0;
bogdanm 13:0645d8841f51 171 }
bogdanm 13:0645d8841f51 172
bogdanm 13:0645d8841f51 173 static void i2c_send_nack(i2c_t *obj) {
bogdanm 13:0645d8841f51 174 obj->i2c->C1 |= I2C_C1_TXAK_MASK; // NACK
bogdanm 13:0645d8841f51 175 }
bogdanm 13:0645d8841f51 176
bogdanm 13:0645d8841f51 177 static void i2c_send_ack(i2c_t *obj) {
bogdanm 13:0645d8841f51 178 obj->i2c->C1 &= ~I2C_C1_TXAK_MASK; // ACK
bogdanm 13:0645d8841f51 179 }
bogdanm 13:0645d8841f51 180
bogdanm 13:0645d8841f51 181 static int i2c_do_write(i2c_t *obj, int value) {
bogdanm 13:0645d8841f51 182 // write the data
bogdanm 13:0645d8841f51 183 obj->i2c->D = value;
bogdanm 13:0645d8841f51 184
bogdanm 13:0645d8841f51 185 // init and wait the end of the transfer
bogdanm 13:0645d8841f51 186 return i2c_wait_end_tx_transfer(obj);
bogdanm 13:0645d8841f51 187 }
bogdanm 13:0645d8841f51 188
bogdanm 13:0645d8841f51 189 static int i2c_do_read(i2c_t *obj, char * data, int last) {
bogdanm 13:0645d8841f51 190 if (last)
bogdanm 13:0645d8841f51 191 i2c_send_nack(obj);
bogdanm 13:0645d8841f51 192 else
bogdanm 13:0645d8841f51 193 i2c_send_ack(obj);
bogdanm 13:0645d8841f51 194
bogdanm 13:0645d8841f51 195 *data = (obj->i2c->D & 0xFF);
bogdanm 13:0645d8841f51 196
bogdanm 13:0645d8841f51 197 // start rx transfer and wait the end of the transfer
bogdanm 13:0645d8841f51 198 return i2c_wait_end_rx_transfer(obj);
bogdanm 13:0645d8841f51 199 }
bogdanm 13:0645d8841f51 200
bogdanm 13:0645d8841f51 201 void i2c_frequency(i2c_t *obj, int hz) {
bogdanm 13:0645d8841f51 202 uint8_t icr = 0;
bogdanm 13:0645d8841f51 203 uint8_t mult = 0;
bogdanm 13:0645d8841f51 204 uint32_t error = 0;
bogdanm 13:0645d8841f51 205 uint32_t p_error = 0xffffffff;
bogdanm 13:0645d8841f51 206 uint32_t ref = 0;
bogdanm 13:0645d8841f51 207 uint8_t i, j;
bogdanm 13:0645d8841f51 208 // bus clk
bogdanm 13:0645d8841f51 209 uint32_t PCLK = 24000000u;
bogdanm 13:0645d8841f51 210 uint32_t pulse = PCLK / (hz * 2);
bogdanm 13:0645d8841f51 211
bogdanm 13:0645d8841f51 212 // we look for the values that minimize the error
bogdanm 13:0645d8841f51 213
bogdanm 13:0645d8841f51 214 // test all the MULT values
bogdanm 13:0645d8841f51 215 for (i = 1; i < 5; i*=2) {
bogdanm 13:0645d8841f51 216 for (j = 0; j < 0x40; j++) {
bogdanm 13:0645d8841f51 217 ref = PCLK / (i*ICR[j]);
bogdanm 13:0645d8841f51 218 if (ref > hz)
bogdanm 13:0645d8841f51 219 continue;
bogdanm 13:0645d8841f51 220 error = hz - ref;
bogdanm 13:0645d8841f51 221 if (error < p_error) {
bogdanm 13:0645d8841f51 222 icr = j;
bogdanm 13:0645d8841f51 223 mult = i/2;
bogdanm 13:0645d8841f51 224 p_error = error;
bogdanm 13:0645d8841f51 225 }
bogdanm 13:0645d8841f51 226 }
bogdanm 13:0645d8841f51 227 }
bogdanm 13:0645d8841f51 228 pulse = icr | (mult << 6);
bogdanm 13:0645d8841f51 229
bogdanm 13:0645d8841f51 230 // I2C Rate
bogdanm 13:0645d8841f51 231 obj->i2c->F = pulse;
bogdanm 13:0645d8841f51 232 }
bogdanm 13:0645d8841f51 233
bogdanm 13:0645d8841f51 234 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
bogdanm 13:0645d8841f51 235 uint8_t count;
bogdanm 13:0645d8841f51 236 char dummy_read, *ptr;
bogdanm 13:0645d8841f51 237
bogdanm 13:0645d8841f51 238 if (i2c_start(obj)) {
bogdanm 13:0645d8841f51 239 i2c_stop(obj);
bogdanm 13:0645d8841f51 240 return I2C_ERROR_BUS_BUSY;
bogdanm 13:0645d8841f51 241 }
bogdanm 13:0645d8841f51 242
bogdanm 13:0645d8841f51 243 if (i2c_do_write(obj, (address | 0x01))) {
bogdanm 13:0645d8841f51 244 i2c_stop(obj);
bogdanm 13:0645d8841f51 245 return I2C_ERROR_NO_SLAVE;
bogdanm 13:0645d8841f51 246 }
bogdanm 13:0645d8841f51 247
bogdanm 13:0645d8841f51 248 // set rx mode
bogdanm 13:0645d8841f51 249 obj->i2c->C1 &= ~I2C_C1_TX_MASK;
bogdanm 13:0645d8841f51 250
bogdanm 13:0645d8841f51 251 // Read in bytes
bogdanm 13:0645d8841f51 252 for (count = 0; count < (length); count++) {
bogdanm 13:0645d8841f51 253 ptr = (count == 0) ? &dummy_read : &data[count - 1];
bogdanm 13:0645d8841f51 254 uint8_t stop_ = (count == (length - 1)) ? 1 : 0;
bogdanm 13:0645d8841f51 255 if (i2c_do_read(obj, ptr, stop_)) {
bogdanm 13:0645d8841f51 256 i2c_stop(obj);
bogdanm 13:0645d8841f51 257 return count;
bogdanm 13:0645d8841f51 258 }
bogdanm 13:0645d8841f51 259 }
bogdanm 13:0645d8841f51 260
bogdanm 13:0645d8841f51 261 // If not repeated start, send stop.
bogdanm 13:0645d8841f51 262 if (stop) {
bogdanm 13:0645d8841f51 263 i2c_stop(obj);
bogdanm 13:0645d8841f51 264 }
bogdanm 13:0645d8841f51 265
bogdanm 13:0645d8841f51 266 // last read
bogdanm 13:0645d8841f51 267 data[count-1] = obj->i2c->D;
bogdanm 13:0645d8841f51 268
bogdanm 13:0645d8841f51 269 return length;
bogdanm 13:0645d8841f51 270 }
bogdanm 13:0645d8841f51 271 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
bogdanm 13:0645d8841f51 272 int i;
bogdanm 13:0645d8841f51 273
bogdanm 13:0645d8841f51 274 if (i2c_start(obj)) {
bogdanm 13:0645d8841f51 275 i2c_stop(obj);
bogdanm 13:0645d8841f51 276 return I2C_ERROR_BUS_BUSY;
bogdanm 13:0645d8841f51 277 }
bogdanm 13:0645d8841f51 278
bogdanm 13:0645d8841f51 279 if (i2c_do_write(obj, (address & 0xFE))) {
bogdanm 13:0645d8841f51 280 i2c_stop(obj);
bogdanm 13:0645d8841f51 281 return I2C_ERROR_NO_SLAVE;
bogdanm 13:0645d8841f51 282 }
bogdanm 13:0645d8841f51 283
bogdanm 13:0645d8841f51 284 for (i = 0; i < length; i++) {
bogdanm 13:0645d8841f51 285 if(i2c_do_write(obj, data[i])) {
bogdanm 13:0645d8841f51 286 i2c_stop(obj);
bogdanm 13:0645d8841f51 287 return i;
bogdanm 13:0645d8841f51 288 }
bogdanm 13:0645d8841f51 289 }
bogdanm 13:0645d8841f51 290
bogdanm 13:0645d8841f51 291 if (stop) {
bogdanm 13:0645d8841f51 292 i2c_stop(obj);
bogdanm 13:0645d8841f51 293 }
bogdanm 13:0645d8841f51 294
bogdanm 13:0645d8841f51 295 return length;
bogdanm 13:0645d8841f51 296 }
bogdanm 13:0645d8841f51 297
bogdanm 13:0645d8841f51 298 void i2c_reset(i2c_t *obj) {
bogdanm 13:0645d8841f51 299 i2c_stop(obj);
bogdanm 13:0645d8841f51 300 }
bogdanm 13:0645d8841f51 301
bogdanm 13:0645d8841f51 302 int i2c_byte_read(i2c_t *obj, int last) {
bogdanm 13:0645d8841f51 303 char data;
bogdanm 13:0645d8841f51 304
bogdanm 13:0645d8841f51 305 // set rx mode
bogdanm 13:0645d8841f51 306 obj->i2c->C1 &= ~I2C_C1_TX_MASK;
bogdanm 13:0645d8841f51 307
bogdanm 13:0645d8841f51 308 if(first_read) {
bogdanm 13:0645d8841f51 309 // first dummy read
bogdanm 13:0645d8841f51 310 i2c_do_read(obj, &data, 0);
bogdanm 13:0645d8841f51 311 first_read = 0;
bogdanm 13:0645d8841f51 312 }
bogdanm 13:0645d8841f51 313
bogdanm 13:0645d8841f51 314 if (last) {
bogdanm 13:0645d8841f51 315 // set tx mode
bogdanm 13:0645d8841f51 316 obj->i2c->C1 |= I2C_C1_TX_MASK;
bogdanm 13:0645d8841f51 317 return obj->i2c->D;
bogdanm 13:0645d8841f51 318 }
bogdanm 13:0645d8841f51 319
bogdanm 13:0645d8841f51 320 i2c_do_read(obj, &data, last);
bogdanm 13:0645d8841f51 321
bogdanm 13:0645d8841f51 322 return data;
bogdanm 13:0645d8841f51 323 }
bogdanm 13:0645d8841f51 324
bogdanm 13:0645d8841f51 325 int i2c_byte_write(i2c_t *obj, int data) {
bogdanm 13:0645d8841f51 326 first_read = 1;
bogdanm 13:0645d8841f51 327
bogdanm 13:0645d8841f51 328 // set tx mode
bogdanm 13:0645d8841f51 329 obj->i2c->C1 |= I2C_C1_TX_MASK;
bogdanm 13:0645d8841f51 330
bogdanm 13:0645d8841f51 331 return !i2c_do_write(obj, (data & 0xFF));
bogdanm 13:0645d8841f51 332 }
bogdanm 13:0645d8841f51 333
bogdanm 13:0645d8841f51 334
bogdanm 13:0645d8841f51 335 #if DEVICE_I2CSLAVE
bogdanm 13:0645d8841f51 336 void i2c_slave_mode(i2c_t *obj, int enable_slave) {
bogdanm 13:0645d8841f51 337 if (enable_slave) {
bogdanm 13:0645d8841f51 338 // set slave mode
bogdanm 13:0645d8841f51 339 obj->i2c->C1 &= ~I2C_C1_MST_MASK;
bogdanm 13:0645d8841f51 340 obj->i2c->C1 |= I2C_C1_IICIE_MASK;
bogdanm 13:0645d8841f51 341 } else {
bogdanm 13:0645d8841f51 342 // set master mode
bogdanm 13:0645d8841f51 343 obj->i2c->C1 |= I2C_C1_MST_MASK;
bogdanm 13:0645d8841f51 344 }
bogdanm 13:0645d8841f51 345 }
bogdanm 13:0645d8841f51 346
bogdanm 13:0645d8841f51 347 int i2c_slave_receive(i2c_t *obj) {
bogdanm 13:0645d8841f51 348 switch(obj->i2c->S) {
bogdanm 13:0645d8841f51 349 // read addressed
bogdanm 13:0645d8841f51 350 case 0xE6: return 1;
bogdanm 13:0645d8841f51 351
bogdanm 13:0645d8841f51 352 // write addressed
bogdanm 13:0645d8841f51 353 case 0xE2: return 3;
bogdanm 13:0645d8841f51 354
bogdanm 13:0645d8841f51 355 default: return 0;
bogdanm 13:0645d8841f51 356 }
bogdanm 13:0645d8841f51 357 }
bogdanm 13:0645d8841f51 358
bogdanm 13:0645d8841f51 359 int i2c_slave_read(i2c_t *obj, char *data, int length) {
bogdanm 13:0645d8841f51 360 uint8_t dummy_read, count;
bogdanm 13:0645d8841f51 361 uint8_t * ptr;
bogdanm 13:0645d8841f51 362
bogdanm 13:0645d8841f51 363 // set rx mode
bogdanm 13:0645d8841f51 364 obj->i2c->C1 &= ~I2C_C1_TX_MASK;
bogdanm 13:0645d8841f51 365
bogdanm 13:0645d8841f51 366 // first dummy read
bogdanm 13:0645d8841f51 367 dummy_read = obj->i2c->D;
bogdanm 13:0645d8841f51 368 if(i2c_wait_end_rx_transfer(obj)) {
bogdanm 13:0645d8841f51 369 return 0;
bogdanm 13:0645d8841f51 370 }
bogdanm 13:0645d8841f51 371
bogdanm 13:0645d8841f51 372 // read address
bogdanm 13:0645d8841f51 373 dummy_read = obj->i2c->D;
bogdanm 13:0645d8841f51 374 if(i2c_wait_end_rx_transfer(obj)) {
bogdanm 13:0645d8841f51 375 return 0;
bogdanm 13:0645d8841f51 376 }
bogdanm 13:0645d8841f51 377
bogdanm 13:0645d8841f51 378 // read (length - 1) bytes
bogdanm 13:0645d8841f51 379 for (count = 0; count < (length - 1); count++) {
bogdanm 13:0645d8841f51 380 data[count] = obj->i2c->D;
bogdanm 13:0645d8841f51 381 if(i2c_wait_end_rx_transfer(obj)) {
bogdanm 13:0645d8841f51 382 return count;
bogdanm 13:0645d8841f51 383 }
bogdanm 13:0645d8841f51 384 }
bogdanm 13:0645d8841f51 385
bogdanm 13:0645d8841f51 386 // read last byte
bogdanm 13:0645d8841f51 387 ptr = (length == 0) ? &dummy_read : (uint8_t *)&data[count];
bogdanm 13:0645d8841f51 388 *ptr = obj->i2c->D;
bogdanm 13:0645d8841f51 389
bogdanm 13:0645d8841f51 390 return (length) ? (count + 1) : 0;
bogdanm 13:0645d8841f51 391 }
bogdanm 13:0645d8841f51 392
bogdanm 13:0645d8841f51 393 int i2c_slave_write(i2c_t *obj, const char *data, int length) {
bogdanm 13:0645d8841f51 394 uint32_t i, count = 0;
bogdanm 13:0645d8841f51 395
bogdanm 13:0645d8841f51 396 // set tx mode
bogdanm 13:0645d8841f51 397 obj->i2c->C1 |= I2C_C1_TX_MASK;
bogdanm 13:0645d8841f51 398
bogdanm 13:0645d8841f51 399 for (i = 0; i < length; i++) {
bogdanm 13:0645d8841f51 400 if(i2c_do_write(obj, data[count++]) == 2) {
bogdanm 13:0645d8841f51 401 return i;
bogdanm 13:0645d8841f51 402 }
bogdanm 13:0645d8841f51 403 }
bogdanm 13:0645d8841f51 404
bogdanm 13:0645d8841f51 405 // set rx mode
bogdanm 13:0645d8841f51 406 obj->i2c->C1 &= ~I2C_C1_TX_MASK;
bogdanm 13:0645d8841f51 407
bogdanm 13:0645d8841f51 408 // dummy rx transfer needed
bogdanm 13:0645d8841f51 409 // otherwise the master cannot generate a stop bit
bogdanm 13:0645d8841f51 410 obj->i2c->D;
bogdanm 13:0645d8841f51 411 if(i2c_wait_end_rx_transfer(obj) == 2) {
bogdanm 13:0645d8841f51 412 return count;
bogdanm 13:0645d8841f51 413 }
bogdanm 13:0645d8841f51 414
bogdanm 13:0645d8841f51 415 return count;
bogdanm 13:0645d8841f51 416 }
bogdanm 13:0645d8841f51 417
bogdanm 13:0645d8841f51 418 void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
bogdanm 13:0645d8841f51 419 obj->i2c->A1 = address & 0xfe;
bogdanm 13:0645d8841f51 420 }
bogdanm 13:0645d8841f51 421 #endif
bogdanm 13:0645d8841f51 422