Steve Kim / mbed-src

Dependents:   AsyncPrint

Fork of mbed-src by mbed official

Committer:
mbed_official
Date:
Wed Jul 23 21:15:06 2014 +0100
Revision:
265:9632ea190e16
Synchronized with git revision 7a5896cba254ab45829b43f6cef5563706ebba2b

Full URL: https://github.com/mbedmicro/mbed/commit/7a5896cba254ab45829b43f6cef5563706ebba2b/

[MTS_GAMBIT] Add new target support

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 265:9632ea190e16 1 /* mbed Microcontroller Library
mbed_official 265:9632ea190e16 2 * Copyright (c) 2006-2013 ARM Limited
mbed_official 265:9632ea190e16 3 *
mbed_official 265:9632ea190e16 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 265:9632ea190e16 5 * you may not use this file except in compliance with the License.
mbed_official 265:9632ea190e16 6 * You may obtain a copy of the License at
mbed_official 265:9632ea190e16 7 *
mbed_official 265:9632ea190e16 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 265:9632ea190e16 9 *
mbed_official 265:9632ea190e16 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 265:9632ea190e16 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 265:9632ea190e16 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 265:9632ea190e16 13 * See the License for the specific language governing permissions and
mbed_official 265:9632ea190e16 14 * limitations under the License.
mbed_official 265:9632ea190e16 15 */
mbed_official 265:9632ea190e16 16 #include "mbed_assert.h"
mbed_official 265:9632ea190e16 17 #include "i2c_api.h"
mbed_official 265:9632ea190e16 18
mbed_official 265:9632ea190e16 19 #include "cmsis.h"
mbed_official 265:9632ea190e16 20 #include "pinmap.h"
mbed_official 265:9632ea190e16 21 #include "fsl_clock_manager.h"
mbed_official 265:9632ea190e16 22 #include "fsl_i2c_hal.h"
mbed_official 265:9632ea190e16 23 #include "fsl_port_hal.h"
mbed_official 265:9632ea190e16 24 #include "fsl_sim_hal.h"
mbed_official 265:9632ea190e16 25
mbed_official 265:9632ea190e16 26 static const PinMap PinMap_I2C_SDA[] = {
mbed_official 265:9632ea190e16 27 {PTE25, I2C_0, 5},
mbed_official 265:9632ea190e16 28 {PTB1 , I2C_0, 2},
mbed_official 265:9632ea190e16 29 {PTB3 , I2C_0, 2},
mbed_official 265:9632ea190e16 30 {PTC11, I2C_1, 2},
mbed_official 265:9632ea190e16 31 {PTA13, I2C_2, 5},
mbed_official 265:9632ea190e16 32 {PTD3 , I2C_0, 7},
mbed_official 265:9632ea190e16 33 {PTE0 , I2C_1, 6},
mbed_official 265:9632ea190e16 34 {NC , NC , 0}
mbed_official 265:9632ea190e16 35 };
mbed_official 265:9632ea190e16 36
mbed_official 265:9632ea190e16 37 static const PinMap PinMap_I2C_SCL[] = {
mbed_official 265:9632ea190e16 38 {PTE24, I2C_0, 5},
mbed_official 265:9632ea190e16 39 {PTB0 , I2C_0, 2},
mbed_official 265:9632ea190e16 40 {PTB2 , I2C_0, 2},
mbed_official 265:9632ea190e16 41 {PTC10, I2C_1, 2},
mbed_official 265:9632ea190e16 42 {PTA12, I2C_2, 5},
mbed_official 265:9632ea190e16 43 {PTA14, I2C_2, 5},
mbed_official 265:9632ea190e16 44 {PTD2 , I2C_0, 7},
mbed_official 265:9632ea190e16 45 {PTE1 , I2C_1, 6},
mbed_official 265:9632ea190e16 46 {NC , NC , 0}
mbed_official 265:9632ea190e16 47 };
mbed_official 265:9632ea190e16 48
mbed_official 265:9632ea190e16 49 void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
mbed_official 265:9632ea190e16 50 uint32_t i2c_sda = pinmap_peripheral(sda, PinMap_I2C_SDA);
mbed_official 265:9632ea190e16 51 uint32_t i2c_scl = pinmap_peripheral(scl, PinMap_I2C_SCL);
mbed_official 265:9632ea190e16 52 obj->instance = pinmap_merge(i2c_sda, i2c_scl);
mbed_official 265:9632ea190e16 53 MBED_ASSERT((int)obj->instance != NC);
mbed_official 265:9632ea190e16 54
mbed_official 265:9632ea190e16 55 clock_manager_set_gate(kClockModuleI2C, obj->instance, true);
mbed_official 265:9632ea190e16 56 clock_manager_set_gate(kClockModulePORT, sda >> GPIO_PORT_SHIFT, true);
mbed_official 265:9632ea190e16 57 clock_manager_set_gate(kClockModulePORT, scl >> GPIO_PORT_SHIFT, true);
mbed_official 265:9632ea190e16 58 i2c_hal_enable(obj->instance);
mbed_official 265:9632ea190e16 59 i2c_frequency(obj, 100000);
mbed_official 265:9632ea190e16 60
mbed_official 265:9632ea190e16 61 pinmap_pinout(sda, PinMap_I2C_SDA);
mbed_official 265:9632ea190e16 62 pinmap_pinout(scl, PinMap_I2C_SCL);
mbed_official 265:9632ea190e16 63 port_hal_configure_open_drain(sda >> GPIO_PORT_SHIFT, sda & 0xFF, true);
mbed_official 265:9632ea190e16 64 port_hal_configure_open_drain(scl >> GPIO_PORT_SHIFT, scl & 0xFF, true);
mbed_official 265:9632ea190e16 65 }
mbed_official 265:9632ea190e16 66
mbed_official 265:9632ea190e16 67 int i2c_start(i2c_t *obj) {
mbed_official 265:9632ea190e16 68 i2c_hal_send_start(obj->instance);
mbed_official 265:9632ea190e16 69 return 0;
mbed_official 265:9632ea190e16 70 }
mbed_official 265:9632ea190e16 71
mbed_official 265:9632ea190e16 72 int i2c_stop(i2c_t *obj) {
mbed_official 265:9632ea190e16 73 volatile uint32_t n = 0;
mbed_official 265:9632ea190e16 74 i2c_hal_send_stop(obj->instance);
mbed_official 265:9632ea190e16 75
mbed_official 265:9632ea190e16 76 // It seems that there are timing problems
mbed_official 265:9632ea190e16 77 // when there is no waiting time after a STOP.
mbed_official 265:9632ea190e16 78 // This wait is also included on the samples
mbed_official 265:9632ea190e16 79 // code provided with the freedom board
mbed_official 265:9632ea190e16 80 for (n = 0; n < 200; n++) __NOP();
mbed_official 265:9632ea190e16 81 return 0;
mbed_official 265:9632ea190e16 82 }
mbed_official 265:9632ea190e16 83
mbed_official 265:9632ea190e16 84 static int timeout_status_poll(i2c_t *obj, uint32_t mask) {
mbed_official 265:9632ea190e16 85 uint32_t i, timeout = 100000;
mbed_official 265:9632ea190e16 86
mbed_official 265:9632ea190e16 87 for (i = 0; i < timeout; i++) {
mbed_official 265:9632ea190e16 88 if (HW_I2C_S_RD(obj->instance) & mask)
mbed_official 265:9632ea190e16 89 return 0;
mbed_official 265:9632ea190e16 90 }
mbed_official 265:9632ea190e16 91 return 1;
mbed_official 265:9632ea190e16 92 }
mbed_official 265:9632ea190e16 93
mbed_official 265:9632ea190e16 94 // this function waits the end of a tx transfer and return the status of the transaction:
mbed_official 265:9632ea190e16 95 // 0: OK ack received
mbed_official 265:9632ea190e16 96 // 1: OK ack not received
mbed_official 265:9632ea190e16 97 // 2: failure
mbed_official 265:9632ea190e16 98 static int i2c_wait_end_tx_transfer(i2c_t *obj) {
mbed_official 265:9632ea190e16 99 // wait for the interrupt flag
mbed_official 265:9632ea190e16 100 if (timeout_status_poll(obj, I2C_S_IICIF_MASK)) {
mbed_official 265:9632ea190e16 101 return 2;
mbed_official 265:9632ea190e16 102 }
mbed_official 265:9632ea190e16 103
mbed_official 265:9632ea190e16 104 i2c_hal_clear_interrupt(obj->instance);
mbed_official 265:9632ea190e16 105
mbed_official 265:9632ea190e16 106 // wait transfer complete
mbed_official 265:9632ea190e16 107 if (timeout_status_poll(obj, I2C_S_TCF_MASK)) {
mbed_official 265:9632ea190e16 108 return 2;
mbed_official 265:9632ea190e16 109 }
mbed_official 265:9632ea190e16 110
mbed_official 265:9632ea190e16 111 // check if we received the ACK or not
mbed_official 265:9632ea190e16 112 return i2c_hal_get_receive_ack(obj->instance) ? 0 : 1;
mbed_official 265:9632ea190e16 113 }
mbed_official 265:9632ea190e16 114
mbed_official 265:9632ea190e16 115 // this function waits the end of a rx transfer and return the status of the transaction:
mbed_official 265:9632ea190e16 116 // 0: OK
mbed_official 265:9632ea190e16 117 // 1: failure
mbed_official 265:9632ea190e16 118 static int i2c_wait_end_rx_transfer(i2c_t *obj) {
mbed_official 265:9632ea190e16 119 // wait for the end of the rx transfer
mbed_official 265:9632ea190e16 120 if (timeout_status_poll(obj, I2C_S_IICIF_MASK)) {
mbed_official 265:9632ea190e16 121 return 1;
mbed_official 265:9632ea190e16 122 }
mbed_official 265:9632ea190e16 123
mbed_official 265:9632ea190e16 124 i2c_hal_clear_interrupt(obj->instance);
mbed_official 265:9632ea190e16 125
mbed_official 265:9632ea190e16 126 return 0;
mbed_official 265:9632ea190e16 127 }
mbed_official 265:9632ea190e16 128
mbed_official 265:9632ea190e16 129 static int i2c_do_write(i2c_t *obj, int value) {
mbed_official 265:9632ea190e16 130 i2c_hal_write(obj->instance, value);
mbed_official 265:9632ea190e16 131
mbed_official 265:9632ea190e16 132 // init and wait the end of the transfer
mbed_official 265:9632ea190e16 133 return i2c_wait_end_tx_transfer(obj);
mbed_official 265:9632ea190e16 134 }
mbed_official 265:9632ea190e16 135
mbed_official 265:9632ea190e16 136 static int i2c_do_read(i2c_t *obj, char * data, int last) {
mbed_official 265:9632ea190e16 137 if (last) {
mbed_official 265:9632ea190e16 138 i2c_hal_send_nak(obj->instance);
mbed_official 265:9632ea190e16 139 } else {
mbed_official 265:9632ea190e16 140 i2c_hal_send_ack(obj->instance);
mbed_official 265:9632ea190e16 141 }
mbed_official 265:9632ea190e16 142
mbed_official 265:9632ea190e16 143 *data = (i2c_hal_read(obj->instance) & 0xFF);
mbed_official 265:9632ea190e16 144
mbed_official 265:9632ea190e16 145 // start rx transfer and wait the end of the transfer
mbed_official 265:9632ea190e16 146 return i2c_wait_end_rx_transfer(obj);
mbed_official 265:9632ea190e16 147 }
mbed_official 265:9632ea190e16 148
mbed_official 265:9632ea190e16 149 void i2c_frequency(i2c_t *obj, int hz) {
mbed_official 265:9632ea190e16 150 uint32_t busClock;
mbed_official 265:9632ea190e16 151
mbed_official 265:9632ea190e16 152 clock_manager_error_code_t error = clock_manager_get_frequency(kBusClock, &busClock);
mbed_official 265:9632ea190e16 153 if (error == kClockManagerSuccess) {
mbed_official 265:9632ea190e16 154 i2c_hal_set_baud(obj->instance, busClock, hz / 1000, NULL);
mbed_official 265:9632ea190e16 155 }
mbed_official 265:9632ea190e16 156 }
mbed_official 265:9632ea190e16 157
mbed_official 265:9632ea190e16 158 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
mbed_official 265:9632ea190e16 159 int count;
mbed_official 265:9632ea190e16 160 char dummy_read, *ptr;
mbed_official 265:9632ea190e16 161
mbed_official 265:9632ea190e16 162 if (i2c_start(obj)) {
mbed_official 265:9632ea190e16 163 i2c_stop(obj);
mbed_official 265:9632ea190e16 164 return I2C_ERROR_BUS_BUSY;
mbed_official 265:9632ea190e16 165 }
mbed_official 265:9632ea190e16 166
mbed_official 265:9632ea190e16 167 if (i2c_do_write(obj, (address | 0x01))) {
mbed_official 265:9632ea190e16 168 i2c_stop(obj);
mbed_official 265:9632ea190e16 169 return I2C_ERROR_NO_SLAVE;
mbed_official 265:9632ea190e16 170 }
mbed_official 265:9632ea190e16 171
mbed_official 265:9632ea190e16 172 // set rx mode
mbed_official 265:9632ea190e16 173 i2c_hal_set_direction(obj->instance, kI2CReceive);
mbed_official 265:9632ea190e16 174
mbed_official 265:9632ea190e16 175 // Read in bytes
mbed_official 265:9632ea190e16 176 for (count = 0; count < (length); count++) {
mbed_official 265:9632ea190e16 177 ptr = (count == 0) ? &dummy_read : &data[count - 1];
mbed_official 265:9632ea190e16 178 uint8_t stop_ = (count == (length - 1)) ? 1 : 0;
mbed_official 265:9632ea190e16 179 if (i2c_do_read(obj, ptr, stop_)) {
mbed_official 265:9632ea190e16 180 i2c_stop(obj);
mbed_official 265:9632ea190e16 181 return count;
mbed_official 265:9632ea190e16 182 }
mbed_official 265:9632ea190e16 183 }
mbed_official 265:9632ea190e16 184
mbed_official 265:9632ea190e16 185 // If not repeated start, send stop.
mbed_official 265:9632ea190e16 186 if (stop)
mbed_official 265:9632ea190e16 187 i2c_stop(obj);
mbed_official 265:9632ea190e16 188
mbed_official 265:9632ea190e16 189 // last read
mbed_official 265:9632ea190e16 190 data[count-1] = i2c_hal_read(obj->instance);
mbed_official 265:9632ea190e16 191
mbed_official 265:9632ea190e16 192 return length;
mbed_official 265:9632ea190e16 193 }
mbed_official 265:9632ea190e16 194
mbed_official 265:9632ea190e16 195 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
mbed_official 265:9632ea190e16 196 int i;
mbed_official 265:9632ea190e16 197
mbed_official 265:9632ea190e16 198 if (i2c_start(obj)) {
mbed_official 265:9632ea190e16 199 i2c_stop(obj);
mbed_official 265:9632ea190e16 200 return I2C_ERROR_BUS_BUSY;
mbed_official 265:9632ea190e16 201 }
mbed_official 265:9632ea190e16 202
mbed_official 265:9632ea190e16 203 if (i2c_do_write(obj, (address & 0xFE))) {
mbed_official 265:9632ea190e16 204 i2c_stop(obj);
mbed_official 265:9632ea190e16 205 return I2C_ERROR_NO_SLAVE;
mbed_official 265:9632ea190e16 206 }
mbed_official 265:9632ea190e16 207
mbed_official 265:9632ea190e16 208 for (i = 0; i < length; i++) {
mbed_official 265:9632ea190e16 209 if(i2c_do_write(obj, data[i])) {
mbed_official 265:9632ea190e16 210 i2c_stop(obj);
mbed_official 265:9632ea190e16 211 return i;
mbed_official 265:9632ea190e16 212 }
mbed_official 265:9632ea190e16 213 }
mbed_official 265:9632ea190e16 214
mbed_official 265:9632ea190e16 215 if (stop)
mbed_official 265:9632ea190e16 216 i2c_stop(obj);
mbed_official 265:9632ea190e16 217
mbed_official 265:9632ea190e16 218 return length;
mbed_official 265:9632ea190e16 219 }
mbed_official 265:9632ea190e16 220
mbed_official 265:9632ea190e16 221 void i2c_reset(i2c_t *obj) {
mbed_official 265:9632ea190e16 222 i2c_stop(obj);
mbed_official 265:9632ea190e16 223 }
mbed_official 265:9632ea190e16 224
mbed_official 265:9632ea190e16 225 int i2c_byte_read(i2c_t *obj, int last) {
mbed_official 265:9632ea190e16 226 char data;
mbed_official 265:9632ea190e16 227
mbed_official 265:9632ea190e16 228 // set rx mode
mbed_official 265:9632ea190e16 229 i2c_hal_set_direction(obj->instance, kI2CReceive);
mbed_official 265:9632ea190e16 230
mbed_official 265:9632ea190e16 231 // Setup read
mbed_official 265:9632ea190e16 232 i2c_do_read(obj, &data, last);
mbed_official 265:9632ea190e16 233
mbed_official 265:9632ea190e16 234 // set tx mode
mbed_official 265:9632ea190e16 235 i2c_hal_set_direction(obj->instance, kI2CTransmit);
mbed_official 265:9632ea190e16 236 return i2c_hal_read(obj->instance);
mbed_official 265:9632ea190e16 237 }
mbed_official 265:9632ea190e16 238
mbed_official 265:9632ea190e16 239 int i2c_byte_write(i2c_t *obj, int data) {
mbed_official 265:9632ea190e16 240 // set tx mode
mbed_official 265:9632ea190e16 241 i2c_hal_set_direction(obj->instance, kI2CTransmit);
mbed_official 265:9632ea190e16 242
mbed_official 265:9632ea190e16 243 return !i2c_do_write(obj, (data & 0xFF));
mbed_official 265:9632ea190e16 244 }
mbed_official 265:9632ea190e16 245
mbed_official 265:9632ea190e16 246
mbed_official 265:9632ea190e16 247 #if DEVICE_I2CSLAVE
mbed_official 265:9632ea190e16 248 void i2c_slave_mode(i2c_t *obj, int enable_slave) {
mbed_official 265:9632ea190e16 249 if (enable_slave) {
mbed_official 265:9632ea190e16 250 // set slave mode
mbed_official 265:9632ea190e16 251 BW_I2C_C1_MST(obj->instance, 0);
mbed_official 265:9632ea190e16 252 i2c_hal_enable_interrupt(obj->instance);
mbed_official 265:9632ea190e16 253 } else {
mbed_official 265:9632ea190e16 254 // set master mode
mbed_official 265:9632ea190e16 255 BW_I2C_C1_MST(obj->instance, 1);
mbed_official 265:9632ea190e16 256 }
mbed_official 265:9632ea190e16 257 }
mbed_official 265:9632ea190e16 258
mbed_official 265:9632ea190e16 259 int i2c_slave_receive(i2c_t *obj) {
mbed_official 265:9632ea190e16 260 switch(HW_I2C_S_RD(obj->instance)) {
mbed_official 265:9632ea190e16 261 // read addressed
mbed_official 265:9632ea190e16 262 case 0xE6:
mbed_official 265:9632ea190e16 263 return 1;
mbed_official 265:9632ea190e16 264 // write addressed
mbed_official 265:9632ea190e16 265 case 0xE2:
mbed_official 265:9632ea190e16 266 return 3;
mbed_official 265:9632ea190e16 267 default:
mbed_official 265:9632ea190e16 268 return 0;
mbed_official 265:9632ea190e16 269 }
mbed_official 265:9632ea190e16 270 }
mbed_official 265:9632ea190e16 271
mbed_official 265:9632ea190e16 272 int i2c_slave_read(i2c_t *obj, char *data, int length) {
mbed_official 265:9632ea190e16 273 uint8_t dummy_read;
mbed_official 265:9632ea190e16 274 uint8_t *ptr;
mbed_official 265:9632ea190e16 275 int count;
mbed_official 265:9632ea190e16 276
mbed_official 265:9632ea190e16 277 // set rx mode
mbed_official 265:9632ea190e16 278 i2c_hal_set_direction(obj->instance, kI2CTransmit);
mbed_official 265:9632ea190e16 279
mbed_official 265:9632ea190e16 280 // first dummy read
mbed_official 265:9632ea190e16 281 dummy_read = i2c_hal_read(obj->instance);
mbed_official 265:9632ea190e16 282 if (i2c_wait_end_rx_transfer(obj))
mbed_official 265:9632ea190e16 283 return 0;
mbed_official 265:9632ea190e16 284
mbed_official 265:9632ea190e16 285 // read address
mbed_official 265:9632ea190e16 286 dummy_read = i2c_hal_read(obj->instance);
mbed_official 265:9632ea190e16 287 if (i2c_wait_end_rx_transfer(obj))
mbed_official 265:9632ea190e16 288 return 0;
mbed_official 265:9632ea190e16 289
mbed_official 265:9632ea190e16 290 // read (length - 1) bytes
mbed_official 265:9632ea190e16 291 for (count = 0; count < (length - 1); count++) {
mbed_official 265:9632ea190e16 292 data[count] = i2c_hal_read(obj->instance);
mbed_official 265:9632ea190e16 293 if (i2c_wait_end_rx_transfer(obj))
mbed_official 265:9632ea190e16 294 return count;
mbed_official 265:9632ea190e16 295 }
mbed_official 265:9632ea190e16 296
mbed_official 265:9632ea190e16 297 // read last byte
mbed_official 265:9632ea190e16 298 ptr = (length == 0) ? &dummy_read : (uint8_t *)&data[count];
mbed_official 265:9632ea190e16 299 *ptr = i2c_hal_read(obj->instance);
mbed_official 265:9632ea190e16 300
mbed_official 265:9632ea190e16 301 return (length) ? (count + 1) : 0;
mbed_official 265:9632ea190e16 302 }
mbed_official 265:9632ea190e16 303
mbed_official 265:9632ea190e16 304 int i2c_slave_write(i2c_t *obj, const char *data, int length) {
mbed_official 265:9632ea190e16 305 int i, count = 0;
mbed_official 265:9632ea190e16 306
mbed_official 265:9632ea190e16 307 // set tx mode
mbed_official 265:9632ea190e16 308 i2c_hal_set_direction(obj->instance, kI2CTransmit);
mbed_official 265:9632ea190e16 309
mbed_official 265:9632ea190e16 310 for (i = 0; i < length; i++) {
mbed_official 265:9632ea190e16 311 if (i2c_do_write(obj, data[count++]) == 2)
mbed_official 265:9632ea190e16 312 return i;
mbed_official 265:9632ea190e16 313 }
mbed_official 265:9632ea190e16 314
mbed_official 265:9632ea190e16 315 // set rx mode
mbed_official 265:9632ea190e16 316 i2c_hal_set_direction(obj->instance, kI2CReceive);
mbed_official 265:9632ea190e16 317
mbed_official 265:9632ea190e16 318 // dummy rx transfer needed
mbed_official 265:9632ea190e16 319 // otherwise the master cannot generate a stop bit
mbed_official 265:9632ea190e16 320 i2c_hal_read(obj->instance);
mbed_official 265:9632ea190e16 321 if (i2c_wait_end_rx_transfer(obj) == 2)
mbed_official 265:9632ea190e16 322 return count;
mbed_official 265:9632ea190e16 323
mbed_official 265:9632ea190e16 324 return count;
mbed_official 265:9632ea190e16 325 }
mbed_official 265:9632ea190e16 326
mbed_official 265:9632ea190e16 327 void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
mbed_official 265:9632ea190e16 328 i2c_hal_set_upper_slave_address_7bit(obj->instance, address & 0xfe);
mbed_official 265:9632ea190e16 329 }
mbed_official 265:9632ea190e16 330 #endif
mbed_official 265:9632ea190e16 331