mbed official / mbed-dev

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
AnnaBridge
Date:
Wed Feb 20 22:31:08 2019 +0000
Revision:
189:f392fc9709a3
Parent:
187:0387e8f68319
mbed library release version 165

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AnnaBridge 181:57724642e740 1 /* mbed Microcontroller Library
AnnaBridge 181:57724642e740 2 * Copyright (c) 2006-2013 ARM Limited
AnnaBridge 181:57724642e740 3 *
AnnaBridge 181:57724642e740 4 * Licensed under the Apache License, Version 2.0 (the "License");
AnnaBridge 181:57724642e740 5 * you may not use this file except in compliance with the License.
AnnaBridge 181:57724642e740 6 * You may obtain a copy of the License at
AnnaBridge 181:57724642e740 7 *
AnnaBridge 181:57724642e740 8 * http://www.apache.org/licenses/LICENSE-2.0
AnnaBridge 181:57724642e740 9 *
AnnaBridge 181:57724642e740 10 * Unless required by applicable law or agreed to in writing, software
AnnaBridge 181:57724642e740 11 * distributed under the License is distributed on an "AS IS" BASIS,
AnnaBridge 181:57724642e740 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
AnnaBridge 181:57724642e740 13 * See the License for the specific language governing permissions and
AnnaBridge 181:57724642e740 14 * limitations under the License.
AnnaBridge 181:57724642e740 15 */
AnnaBridge 181:57724642e740 16 #include "mbed_assert.h"
AnnaBridge 181:57724642e740 17 #include "i2c_api.h"
AnnaBridge 181:57724642e740 18
AnnaBridge 181:57724642e740 19 #if DEVICE_I2C
AnnaBridge 181:57724642e740 20
AnnaBridge 181:57724642e740 21 #include "cmsis.h"
AnnaBridge 181:57724642e740 22 #include "pinmap.h"
AnnaBridge 181:57724642e740 23 #include "fsl_lpi2c.h"
AnnaBridge 181:57724642e740 24 #include "PeripheralPins.h"
AnnaBridge 181:57724642e740 25
AnnaBridge 181:57724642e740 26 /* Array of I2C peripheral base address. */
AnnaBridge 181:57724642e740 27 static LPI2C_Type *const i2c_addrs[] = LPI2C_BASE_PTRS;
AnnaBridge 181:57724642e740 28
AnnaBridge 181:57724642e740 29 extern void i2c_setup_clock();
AnnaBridge 181:57724642e740 30 extern uint32_t i2c_get_clock();
AnnaBridge 181:57724642e740 31 void pin_mode_opendrain(PinName pin, bool enable);
AnnaBridge 181:57724642e740 32
AnnaBridge 181:57724642e740 33 void i2c_init(i2c_t *obj, PinName sda, PinName scl)
AnnaBridge 181:57724642e740 34 {
AnnaBridge 181:57724642e740 35 uint32_t i2c_sda = pinmap_peripheral(sda, PinMap_I2C_SDA);
AnnaBridge 181:57724642e740 36 uint32_t i2c_scl = pinmap_peripheral(scl, PinMap_I2C_SCL);
AnnaBridge 181:57724642e740 37 obj->instance = pinmap_merge(i2c_sda, i2c_scl);
AnnaBridge 187:0387e8f68319 38
AnnaBridge 181:57724642e740 39 MBED_ASSERT((int)obj->instance != NC);
AnnaBridge 181:57724642e740 40
AnnaBridge 181:57724642e740 41 lpi2c_master_config_t master_config;
AnnaBridge 181:57724642e740 42
AnnaBridge 181:57724642e740 43 i2c_setup_clock();
AnnaBridge 181:57724642e740 44
AnnaBridge 181:57724642e740 45 LPI2C_MasterGetDefaultConfig(&master_config);
AnnaBridge 181:57724642e740 46 LPI2C_MasterInit(i2c_addrs[obj->instance], &master_config, i2c_get_clock());
AnnaBridge 181:57724642e740 47
AnnaBridge 181:57724642e740 48 pinmap_pinout(sda, PinMap_I2C_SDA);
AnnaBridge 181:57724642e740 49 pinmap_pinout(scl, PinMap_I2C_SCL);
AnnaBridge 181:57724642e740 50
AnnaBridge 187:0387e8f68319 51 pin_mode(sda, PullUp_22K);
AnnaBridge 187:0387e8f68319 52 pin_mode(scl, PullUp_22K);
AnnaBridge 187:0387e8f68319 53
AnnaBridge 181:57724642e740 54 pin_mode_opendrain(sda, true);
AnnaBridge 181:57724642e740 55 pin_mode_opendrain(scl, true);
AnnaBridge 181:57724642e740 56 }
AnnaBridge 181:57724642e740 57
AnnaBridge 181:57724642e740 58 int i2c_start(i2c_t *obj)
AnnaBridge 181:57724642e740 59 {
AnnaBridge 187:0387e8f68319 60 LPI2C_Type *base = i2c_addrs[obj->instance];
AnnaBridge 187:0387e8f68319 61 int status = 0;
AnnaBridge 187:0387e8f68319 62
AnnaBridge 187:0387e8f68319 63 obj->address_set = 0;
AnnaBridge 181:57724642e740 64
AnnaBridge 187:0387e8f68319 65 /* Clear all flags. */
AnnaBridge 187:0387e8f68319 66 LPI2C_MasterClearStatusFlags(base, kLPI2C_MasterEndOfPacketFlag |
AnnaBridge 187:0387e8f68319 67 kLPI2C_MasterStopDetectFlag |
AnnaBridge 187:0387e8f68319 68 kLPI2C_MasterNackDetectFlag |
AnnaBridge 187:0387e8f68319 69 kLPI2C_MasterArbitrationLostFlag |
AnnaBridge 187:0387e8f68319 70 kLPI2C_MasterFifoErrFlag |
AnnaBridge 187:0387e8f68319 71 kLPI2C_MasterPinLowTimeoutFlag |
AnnaBridge 187:0387e8f68319 72 kLPI2C_MasterDataMatchFlag);
AnnaBridge 187:0387e8f68319 73
AnnaBridge 187:0387e8f68319 74 /* Turn off auto-stop option. */
AnnaBridge 187:0387e8f68319 75 base->MCFGR1 &= ~LPI2C_MCFGR1_AUTOSTOP_MASK;
AnnaBridge 187:0387e8f68319 76
AnnaBridge 187:0387e8f68319 77 return status;
AnnaBridge 181:57724642e740 78 }
AnnaBridge 181:57724642e740 79
AnnaBridge 181:57724642e740 80 int i2c_stop(i2c_t *obj)
AnnaBridge 181:57724642e740 81 {
AnnaBridge 181:57724642e740 82 if (LPI2C_MasterStop(i2c_addrs[obj->instance]) != kStatus_Success) {
AnnaBridge 181:57724642e740 83 return 1;
AnnaBridge 181:57724642e740 84 }
AnnaBridge 181:57724642e740 85
AnnaBridge 187:0387e8f68319 86 obj->address_set = 0;
AnnaBridge 187:0387e8f68319 87
AnnaBridge 181:57724642e740 88 return 0;
AnnaBridge 181:57724642e740 89 }
AnnaBridge 181:57724642e740 90
AnnaBridge 181:57724642e740 91 void i2c_frequency(i2c_t *obj, int hz)
AnnaBridge 181:57724642e740 92 {
AnnaBridge 181:57724642e740 93 uint32_t busClock;
AnnaBridge 181:57724642e740 94
AnnaBridge 181:57724642e740 95 busClock = i2c_get_clock();
AnnaBridge 187:0387e8f68319 96 LPI2C_MasterSetBaudRate(i2c_addrs[obj->instance], busClock, hz);
AnnaBridge 181:57724642e740 97 }
AnnaBridge 181:57724642e740 98
AnnaBridge 181:57724642e740 99 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
AnnaBridge 181:57724642e740 100 {
AnnaBridge 181:57724642e740 101 LPI2C_Type *base = i2c_addrs[obj->instance];
AnnaBridge 181:57724642e740 102 lpi2c_master_transfer_t master_xfer;
AnnaBridge 181:57724642e740 103
AnnaBridge 181:57724642e740 104 memset(&master_xfer, 0, sizeof(master_xfer));
AnnaBridge 181:57724642e740 105 master_xfer.slaveAddress = address >> 1;
AnnaBridge 181:57724642e740 106 master_xfer.direction = kLPI2C_Read;
AnnaBridge 181:57724642e740 107 master_xfer.data = (uint8_t *)data;
AnnaBridge 181:57724642e740 108 master_xfer.dataSize = length;
AnnaBridge 181:57724642e740 109 if (!stop) {
AnnaBridge 181:57724642e740 110 master_xfer.flags |= kLPI2C_TransferNoStopFlag;
AnnaBridge 181:57724642e740 111 }
AnnaBridge 181:57724642e740 112
AnnaBridge 181:57724642e740 113 /* The below function will issue a STOP signal at the end of the transfer.
AnnaBridge 181:57724642e740 114 * This is required by the hardware in order to receive the last byte
AnnaBridge 181:57724642e740 115 */
AnnaBridge 181:57724642e740 116 if (LPI2C_MasterTransferBlocking(base, &master_xfer) != kStatus_Success) {
AnnaBridge 181:57724642e740 117 return I2C_ERROR_NO_SLAVE;
AnnaBridge 181:57724642e740 118 }
AnnaBridge 181:57724642e740 119
AnnaBridge 181:57724642e740 120 return length;
AnnaBridge 181:57724642e740 121 }
AnnaBridge 181:57724642e740 122
AnnaBridge 181:57724642e740 123 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
AnnaBridge 181:57724642e740 124 {
AnnaBridge 181:57724642e740 125 LPI2C_Type *base = i2c_addrs[obj->instance];
AnnaBridge 181:57724642e740 126 lpi2c_master_transfer_t master_xfer;
AnnaBridge 181:57724642e740 127
AnnaBridge 181:57724642e740 128 if (length == 0) {
AnnaBridge 181:57724642e740 129 if (LPI2C_MasterStart(base, address >> 1, kLPI2C_Write) != kStatus_Success) {
AnnaBridge 181:57724642e740 130 return I2C_ERROR_NO_SLAVE;
AnnaBridge 181:57724642e740 131 }
AnnaBridge 181:57724642e740 132
AnnaBridge 187:0387e8f68319 133 /* Wait till START has been flushed out of the FIFO */
AnnaBridge 187:0387e8f68319 134 while (!(base->MSR & kLPI2C_MasterBusBusyFlag)) {
AnnaBridge 187:0387e8f68319 135 }
AnnaBridge 187:0387e8f68319 136
AnnaBridge 187:0387e8f68319 137 /* Send the STOP signal */
AnnaBridge 187:0387e8f68319 138 base->MTDR = LPI2C_MTDR_CMD(0x2U);
AnnaBridge 187:0387e8f68319 139
AnnaBridge 187:0387e8f68319 140 /* Wait till STOP has been sent successfully */
AnnaBridge 187:0387e8f68319 141 while (!(base->MSR & kLPI2C_MasterStopDetectFlag)) {
AnnaBridge 187:0387e8f68319 142 }
AnnaBridge 187:0387e8f68319 143
AnnaBridge 181:57724642e740 144 if (base->MSR & kLPI2C_MasterNackDetectFlag) {
AnnaBridge 181:57724642e740 145 return I2C_ERROR_NO_SLAVE;
AnnaBridge 181:57724642e740 146 } else {
AnnaBridge 181:57724642e740 147 return length;
AnnaBridge 181:57724642e740 148 }
AnnaBridge 181:57724642e740 149 }
AnnaBridge 181:57724642e740 150
AnnaBridge 181:57724642e740 151 memset(&master_xfer, 0, sizeof(master_xfer));
AnnaBridge 181:57724642e740 152 master_xfer.slaveAddress = address >> 1;
AnnaBridge 181:57724642e740 153 master_xfer.direction = kLPI2C_Write;
AnnaBridge 181:57724642e740 154 master_xfer.data = (uint8_t *)data;
AnnaBridge 181:57724642e740 155 master_xfer.dataSize = length;
AnnaBridge 181:57724642e740 156 if (!stop) {
AnnaBridge 181:57724642e740 157 master_xfer.flags |= kLPI2C_TransferNoStopFlag;
AnnaBridge 181:57724642e740 158 }
AnnaBridge 181:57724642e740 159
AnnaBridge 181:57724642e740 160 if (LPI2C_MasterTransferBlocking(base, &master_xfer) != kStatus_Success) {
AnnaBridge 181:57724642e740 161 return I2C_ERROR_NO_SLAVE;
AnnaBridge 181:57724642e740 162 }
AnnaBridge 181:57724642e740 163
AnnaBridge 181:57724642e740 164 return length;
AnnaBridge 181:57724642e740 165 }
AnnaBridge 181:57724642e740 166
AnnaBridge 181:57724642e740 167 void i2c_reset(i2c_t *obj)
AnnaBridge 181:57724642e740 168 {
AnnaBridge 181:57724642e740 169 i2c_stop(obj);
AnnaBridge 181:57724642e740 170 }
AnnaBridge 181:57724642e740 171
AnnaBridge 181:57724642e740 172 int i2c_byte_read(i2c_t *obj, int last)
AnnaBridge 181:57724642e740 173 {
AnnaBridge 181:57724642e740 174 uint8_t data;
AnnaBridge 181:57724642e740 175 LPI2C_Type *base = i2c_addrs[obj->instance];
AnnaBridge 181:57724642e740 176 lpi2c_master_transfer_t master_xfer;
AnnaBridge 181:57724642e740 177
AnnaBridge 181:57724642e740 178 memset(&master_xfer, 0, sizeof(master_xfer));
AnnaBridge 181:57724642e740 179 master_xfer.direction = kLPI2C_Read;
AnnaBridge 181:57724642e740 180 master_xfer.data = &data;
AnnaBridge 181:57724642e740 181 master_xfer.dataSize = 1;
AnnaBridge 187:0387e8f68319 182 master_xfer.flags = kLPI2C_TransferNoStopFlag | kLPI2C_TransferNoStartFlag;
AnnaBridge 181:57724642e740 183
AnnaBridge 181:57724642e740 184 if (LPI2C_MasterTransferBlocking(base, &master_xfer) != kStatus_Success) {
AnnaBridge 181:57724642e740 185 return I2C_ERROR_NO_SLAVE;
AnnaBridge 181:57724642e740 186 }
AnnaBridge 181:57724642e740 187 return data;
AnnaBridge 181:57724642e740 188 }
AnnaBridge 181:57724642e740 189
AnnaBridge 181:57724642e740 190 int i2c_byte_write(i2c_t *obj, int data)
AnnaBridge 181:57724642e740 191 {
AnnaBridge 181:57724642e740 192 LPI2C_Type *base = i2c_addrs[obj->instance];
AnnaBridge 187:0387e8f68319 193 uint32_t status;
AnnaBridge 187:0387e8f68319 194 size_t txCount;
AnnaBridge 187:0387e8f68319 195 size_t txFifoSize = FSL_FEATURE_LPI2C_FIFO_SIZEn(base);
AnnaBridge 187:0387e8f68319 196
AnnaBridge 187:0387e8f68319 197 /* Clear error flags. */
AnnaBridge 187:0387e8f68319 198 LPI2C_MasterClearStatusFlags(base, LPI2C_MasterGetStatusFlags(base));
AnnaBridge 187:0387e8f68319 199
AnnaBridge 187:0387e8f68319 200 /* Wait till there is room in the TX FIFO */
AnnaBridge 187:0387e8f68319 201 do {
AnnaBridge 187:0387e8f68319 202 /* Get the number of words in the tx fifo and compute empty slots. */
AnnaBridge 187:0387e8f68319 203 LPI2C_MasterGetFifoCounts(base, NULL, &txCount);
AnnaBridge 187:0387e8f68319 204 txCount = txFifoSize - txCount;
AnnaBridge 187:0387e8f68319 205 } while (!txCount);
AnnaBridge 181:57724642e740 206
AnnaBridge 187:0387e8f68319 207 if (!obj->address_set) {
AnnaBridge 187:0387e8f68319 208 obj->address_set = 1;
AnnaBridge 187:0387e8f68319 209 /* Issue start command. */
AnnaBridge 187:0387e8f68319 210 base->MTDR = LPI2C_MTDR_CMD(0x4U) | LPI2C_MTDR_DATA(data);
AnnaBridge 187:0387e8f68319 211 } else {
AnnaBridge 187:0387e8f68319 212 /* Write byte into LPI2C master data register. */
AnnaBridge 187:0387e8f68319 213 base->MTDR = data;
AnnaBridge 187:0387e8f68319 214 }
AnnaBridge 181:57724642e740 215
AnnaBridge 187:0387e8f68319 216 /* Wait till data is pushed out of the FIFO */
AnnaBridge 187:0387e8f68319 217 while (!(base->MSR & kLPI2C_MasterTxReadyFlag)) {
AnnaBridge 187:0387e8f68319 218 }
AnnaBridge 181:57724642e740 219
AnnaBridge 187:0387e8f68319 220 status = LPI2C_MasterCheckAndClearError(base, LPI2C_MasterGetStatusFlags(base));
AnnaBridge 187:0387e8f68319 221 if (status == kStatus_Success) {
AnnaBridge 181:57724642e740 222 return 1;
AnnaBridge 187:0387e8f68319 223 } else if (status == kStatus_LPI2C_Nak) {
AnnaBridge 181:57724642e740 224 return 0;
AnnaBridge 181:57724642e740 225 } else {
AnnaBridge 181:57724642e740 226 return 2;
AnnaBridge 181:57724642e740 227 }
AnnaBridge 181:57724642e740 228 }
AnnaBridge 181:57724642e740 229
AnnaBridge 181:57724642e740 230
AnnaBridge 181:57724642e740 231 #if DEVICE_I2CSLAVE
AnnaBridge 181:57724642e740 232 void i2c_slave_mode(i2c_t *obj, int enable_slave)
AnnaBridge 181:57724642e740 233 {
AnnaBridge 181:57724642e740 234 lpi2c_slave_config_t slave_config;
AnnaBridge 181:57724642e740 235 LPI2C_SlaveGetDefaultConfig(&slave_config);
AnnaBridge 181:57724642e740 236 slave_config.enableSlave = (bool)enable_slave;
AnnaBridge 181:57724642e740 237
AnnaBridge 181:57724642e740 238 LPI2C_SlaveInit(i2c_addrs[obj->instance], &slave_config, i2c_get_clock());
AnnaBridge 181:57724642e740 239 }
AnnaBridge 181:57724642e740 240
AnnaBridge 181:57724642e740 241 int i2c_slave_receive(i2c_t *obj)
AnnaBridge 181:57724642e740 242 {
AnnaBridge 181:57724642e740 243 LPI2C_Type *base = i2c_addrs[obj->instance];
AnnaBridge 181:57724642e740 244 uint32_t status_flags = LPI2C_SlaveGetStatusFlags(base);
AnnaBridge 181:57724642e740 245
AnnaBridge 181:57724642e740 246 if (status_flags & kLPI2C_SlaveAddressValidFlag) {
AnnaBridge 181:57724642e740 247 if (base->SASR & kLPI2C_Read) {
AnnaBridge 181:57724642e740 248 // read addressed
AnnaBridge 181:57724642e740 249 return 1;
AnnaBridge 181:57724642e740 250 } else {
AnnaBridge 181:57724642e740 251 // write addressed
AnnaBridge 181:57724642e740 252 return 3;
AnnaBridge 181:57724642e740 253 }
AnnaBridge 181:57724642e740 254 } else {
AnnaBridge 181:57724642e740 255 // slave not addressed
AnnaBridge 181:57724642e740 256 return 0;
AnnaBridge 181:57724642e740 257 }
AnnaBridge 181:57724642e740 258 }
AnnaBridge 181:57724642e740 259
AnnaBridge 181:57724642e740 260 int i2c_slave_read(i2c_t *obj, char *data, int length)
AnnaBridge 181:57724642e740 261 {
AnnaBridge 181:57724642e740 262 LPI2C_Type *base = i2c_addrs[obj->instance];
AnnaBridge 181:57724642e740 263 int actual_rx;
AnnaBridge 181:57724642e740 264
AnnaBridge 181:57724642e740 265 LPI2C_SlaveReceive(base, (uint8_t *)data, length, (size_t *)&actual_rx);
AnnaBridge 181:57724642e740 266
AnnaBridge 181:57724642e740 267 return actual_rx;
AnnaBridge 181:57724642e740 268 }
AnnaBridge 181:57724642e740 269
AnnaBridge 181:57724642e740 270 int i2c_slave_write(i2c_t *obj, const char *data, int length)
AnnaBridge 181:57724642e740 271 {
AnnaBridge 181:57724642e740 272 LPI2C_Type *base = i2c_addrs[obj->instance];
AnnaBridge 181:57724642e740 273 int actual_rx;
AnnaBridge 181:57724642e740 274
AnnaBridge 181:57724642e740 275 LPI2C_SlaveSend(base, (uint8_t *)data, length, (size_t *)&actual_rx);
AnnaBridge 181:57724642e740 276
AnnaBridge 181:57724642e740 277 return actual_rx;
AnnaBridge 181:57724642e740 278 }
AnnaBridge 181:57724642e740 279
AnnaBridge 181:57724642e740 280 void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask)
AnnaBridge 181:57724642e740 281 {
AnnaBridge 181:57724642e740 282 i2c_addrs[obj->instance]->SAMR = LPI2C_SAMR_ADDR0(address & 0xfe);
AnnaBridge 181:57724642e740 283 }
AnnaBridge 181:57724642e740 284 #endif
AnnaBridge 181:57724642e740 285
AnnaBridge 181:57724642e740 286 #endif