Color Oled(SSD1331) connect to STMicroelectronics Nucleo-F466

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Thu Oct 11 02:27:46 2018 +0000
Revision:
3:f3764f852aa8
Parent:
0:8fdf9a60065b
Nucreo 446 + SSD1331 test version;

Who changed what in which revision?

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