mbed library with additional peripherals for ST F401 board

Fork of mbed-src by mbed official

This mbed LIB has additional peripherals for ST F401 board

  • UART2 : PA_3 rx, PA_2 tx
  • UART3 : PC_7 rx, PC_6 tx
  • I2C2 : PB_3 SDA, PB_10 SCL
  • I2C3 : PB_4 SDA, PA_8 SCL
Committer:
mbed_official
Date:
Mon Jan 13 10:45:05 2014 +0000
Revision:
72:248c61396e08
Parent:
19:398f4c622e1b
Synchronized with git revision f1904ba15c06215a7530efd2d5a16c25af9d29ff

Full URL: https://github.com/mbedmicro/mbed/commit/f1904ba15c06215a7530efd2d5a16c25af9d29ff/

KL46Z: Added Sleep, LED3 and LED4 definitions, switches

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