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:
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