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:
Fri Sep 11 09:30:09 2015 +0100
Revision:
621:9c82b0f79f3d
Parent:
514:7668256dbe61
Synchronized with git revision 6c1d63e069ab9bd86de92e8296ca783681257538

Full URL: https://github.com/mbedmicro/mbed/commit/6c1d63e069ab9bd86de92e8296ca783681257538/

ignore target files not supported by the yotta module

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 514:7668256dbe61 1 /*******************************************************************************
mbed_official 514:7668256dbe61 2 * Copyright (C) 2015 Maxim Integrated Products, Inc., All Rights Reserved.
mbed_official 514:7668256dbe61 3 *
mbed_official 514:7668256dbe61 4 * Permission is hereby granted, free of charge, to any person obtaining a
mbed_official 514:7668256dbe61 5 * copy of this software and associated documentation files (the "Software"),
mbed_official 514:7668256dbe61 6 * to deal in the Software without restriction, including without limitation
mbed_official 514:7668256dbe61 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
mbed_official 514:7668256dbe61 8 * and/or sell copies of the Software, and to permit persons to whom the
mbed_official 514:7668256dbe61 9 * Software is furnished to do so, subject to the following conditions:
mbed_official 514:7668256dbe61 10 *
mbed_official 514:7668256dbe61 11 * The above copyright notice and this permission notice shall be included
mbed_official 514:7668256dbe61 12 * in all copies or substantial portions of the Software.
mbed_official 514:7668256dbe61 13 *
mbed_official 514:7668256dbe61 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
mbed_official 514:7668256dbe61 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
mbed_official 514:7668256dbe61 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
mbed_official 514:7668256dbe61 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
mbed_official 514:7668256dbe61 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
mbed_official 514:7668256dbe61 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
mbed_official 514:7668256dbe61 20 * OTHER DEALINGS IN THE SOFTWARE.
mbed_official 514:7668256dbe61 21 *
mbed_official 514:7668256dbe61 22 * Except as contained in this notice, the name of Maxim Integrated
mbed_official 514:7668256dbe61 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
mbed_official 514:7668256dbe61 24 * Products, Inc. Branding Policy.
mbed_official 514:7668256dbe61 25 *
mbed_official 514:7668256dbe61 26 * The mere transfer of this software does not imply any licenses
mbed_official 514:7668256dbe61 27 * of trade secrets, proprietary technology, copyrights, patents,
mbed_official 514:7668256dbe61 28 * trademarks, maskwork rights, or any other form of intellectual
mbed_official 514:7668256dbe61 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
mbed_official 514:7668256dbe61 30 * ownership rights.
mbed_official 514:7668256dbe61 31 *******************************************************************************
mbed_official 514:7668256dbe61 32 */
mbed_official 514:7668256dbe61 33
mbed_official 514:7668256dbe61 34 #include "mbed_assert.h"
mbed_official 514:7668256dbe61 35 #include "i2c_api.h"
mbed_official 514:7668256dbe61 36 #include "cmsis.h"
mbed_official 514:7668256dbe61 37 #include "i2cm_regs.h"
mbed_official 514:7668256dbe61 38 #include "clkman_regs.h"
mbed_official 514:7668256dbe61 39 #include "ioman_regs.h"
mbed_official 514:7668256dbe61 40 #include "PeripheralPins.h"
mbed_official 514:7668256dbe61 41
mbed_official 514:7668256dbe61 42 #define I2C_SLAVE_ADDR_READ_BIT 0x0001
mbed_official 514:7668256dbe61 43
mbed_official 514:7668256dbe61 44 #ifndef MXC_I2CM_TX_TIMEOUT
mbed_official 514:7668256dbe61 45 #define MXC_I2CM_TX_TIMEOUT 0x5000
mbed_official 514:7668256dbe61 46 #endif
mbed_official 514:7668256dbe61 47
mbed_official 514:7668256dbe61 48 #ifndef MXC_I2CM_RX_TIMEOUT
mbed_official 514:7668256dbe61 49 #define MXC_I2CM_RX_TIMEOUT 0x5000
mbed_official 514:7668256dbe61 50 #endif
mbed_official 514:7668256dbe61 51
mbed_official 514:7668256dbe61 52 typedef enum {
mbed_official 514:7668256dbe61 53 /** 100KHz */
mbed_official 514:7668256dbe61 54 MXC_E_I2CM_SPEED_100KHZ = 0,
mbed_official 514:7668256dbe61 55 /** 400KHz */
mbed_official 514:7668256dbe61 56 MXC_E_I2CM_SPEED_400KHZ,
mbed_official 514:7668256dbe61 57 /** 1MHz */
mbed_official 514:7668256dbe61 58 MXC_E_I2CM_SPEED_1MHZ
mbed_official 514:7668256dbe61 59 } i2cm_speed_t;
mbed_official 514:7668256dbe61 60
mbed_official 514:7668256dbe61 61 /* Clock divider lookup table */
mbed_official 514:7668256dbe61 62 static const uint32_t clk_div_table[3][8] = {
mbed_official 514:7668256dbe61 63 /* MXC_E_I2CM_SPEED_100KHZ */
mbed_official 514:7668256dbe61 64 {
mbed_official 514:7668256dbe61 65 /* 0: */ 0, /* not supported */
mbed_official 514:7668256dbe61 66 /* 1: 6MHz */ (( 3 << MXC_F_I2CM_CLK_DIV_FILTER_CLK_DIV_POS) | ( 7 << MXC_F_I2CM_CLK_DIV_SCL_HI_CNT_POS) | ( 36 << MXC_F_I2CM_CLK_DIV_SCL_LO_CNT_POS)),
mbed_official 514:7668256dbe61 67 /* 2: 8MHz */ (( 4 << MXC_F_I2CM_CLK_DIV_FILTER_CLK_DIV_POS) | (10 << MXC_F_I2CM_CLK_DIV_SCL_HI_CNT_POS) | ( 48 << MXC_F_I2CM_CLK_DIV_SCL_LO_CNT_POS)),
mbed_official 514:7668256dbe61 68 /* 3: 12MHz */ (( 6 << MXC_F_I2CM_CLK_DIV_FILTER_CLK_DIV_POS) | (17 << MXC_F_I2CM_CLK_DIV_SCL_HI_CNT_POS) | ( 72 << MXC_F_I2CM_CLK_DIV_SCL_LO_CNT_POS)),
mbed_official 514:7668256dbe61 69 /* 4: 16MHz */ (( 8 << MXC_F_I2CM_CLK_DIV_FILTER_CLK_DIV_POS) | (24 << MXC_F_I2CM_CLK_DIV_SCL_HI_CNT_POS) | ( 96 << MXC_F_I2CM_CLK_DIV_SCL_LO_CNT_POS)),
mbed_official 514:7668256dbe61 70 /* 5: */ 0, /* not supported */
mbed_official 514:7668256dbe61 71 /* 6: */ 0, /* not supported */
mbed_official 514:7668256dbe61 72 /* 7: 24MHz */ ((12 << MXC_F_I2CM_CLK_DIV_FILTER_CLK_DIV_POS) | (38 << MXC_F_I2CM_CLK_DIV_SCL_HI_CNT_POS) | (144 << MXC_F_I2CM_CLK_DIV_SCL_LO_CNT_POS)),
mbed_official 514:7668256dbe61 73 },
mbed_official 514:7668256dbe61 74 /* MXC_E_I2CM_SPEED_400KHZ */
mbed_official 514:7668256dbe61 75 {
mbed_official 514:7668256dbe61 76 /* 0: */ 0, /* not supported */
mbed_official 514:7668256dbe61 77 /* 1: */ 0, /* not supported */
mbed_official 514:7668256dbe61 78 /* 2: */ 0, /* not supported */
mbed_official 514:7668256dbe61 79 /* 3: 12MHz */ ((2 << MXC_F_I2CM_CLK_DIV_FILTER_CLK_DIV_POS) | (1 << MXC_F_I2CM_CLK_DIV_SCL_HI_CNT_POS) | (18 << MXC_F_I2CM_CLK_DIV_SCL_LO_CNT_POS)),
mbed_official 514:7668256dbe61 80 /* 4: 16MHz */ ((2 << MXC_F_I2CM_CLK_DIV_FILTER_CLK_DIV_POS) | (2 << MXC_F_I2CM_CLK_DIV_SCL_HI_CNT_POS) | (24 << MXC_F_I2CM_CLK_DIV_SCL_LO_CNT_POS)),
mbed_official 514:7668256dbe61 81 /* 5: */ 0, /* not supported */
mbed_official 514:7668256dbe61 82 /* 6: */ 0, /* not supported */
mbed_official 514:7668256dbe61 83 /* 7: 24MHz */ ((3 << MXC_F_I2CM_CLK_DIV_FILTER_CLK_DIV_POS) | (5 << MXC_F_I2CM_CLK_DIV_SCL_HI_CNT_POS) | (36 << MXC_F_I2CM_CLK_DIV_SCL_LO_CNT_POS)),
mbed_official 514:7668256dbe61 84 },
mbed_official 514:7668256dbe61 85 /* MXC_E_I2CM_SPEED_1MHZ */
mbed_official 514:7668256dbe61 86 {
mbed_official 514:7668256dbe61 87 /* 0: */ 0, /* not supported */
mbed_official 514:7668256dbe61 88 /* 1: */ 0, /* not supported */
mbed_official 514:7668256dbe61 89 /* 2: */ 0, /* not supported */
mbed_official 514:7668256dbe61 90 /* 3: */ 0, /* not supported */
mbed_official 514:7668256dbe61 91 /* 4: */ 0, /* not supported */
mbed_official 514:7668256dbe61 92 /* 5: */ 0, /* not supported */
mbed_official 514:7668256dbe61 93 /* 6: */ 0, /* not supported */
mbed_official 514:7668256dbe61 94 /* 7: 24MHz */ ((1 << MXC_F_I2CM_CLK_DIV_FILTER_CLK_DIV_POS) | (0 << MXC_F_I2CM_CLK_DIV_SCL_HI_CNT_POS) | (14 << MXC_F_I2CM_CLK_DIV_SCL_LO_CNT_POS)),
mbed_official 514:7668256dbe61 95 },
mbed_official 514:7668256dbe61 96 };
mbed_official 514:7668256dbe61 97
mbed_official 514:7668256dbe61 98 void i2c_init(i2c_t *obj, PinName sda, PinName scl)
mbed_official 514:7668256dbe61 99 {
mbed_official 514:7668256dbe61 100 // determine the I2C to use
mbed_official 514:7668256dbe61 101 I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
mbed_official 514:7668256dbe61 102 I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
mbed_official 514:7668256dbe61 103 mxc_i2cm_regs_t *i2c = (mxc_i2cm_regs_t*)pinmap_merge(i2c_sda, i2c_scl);
mbed_official 514:7668256dbe61 104 MBED_ASSERT((int)i2c != NC);
mbed_official 514:7668256dbe61 105
mbed_official 514:7668256dbe61 106 obj->i2c = i2c;
mbed_official 514:7668256dbe61 107 obj->txfifo = (uint16_t*)MXC_I2CM_GET_BASE_TX_FIFO(MXC_I2CM_BASE_TO_INSTANCE(i2c));
mbed_official 514:7668256dbe61 108 obj->rxfifo = (uint16_t*)MXC_I2CM_GET_BASE_RX_FIFO(MXC_I2CM_BASE_TO_INSTANCE(i2c));
mbed_official 514:7668256dbe61 109 obj->start_pending = 0;
mbed_official 514:7668256dbe61 110 obj->stop_pending = 0;
mbed_official 514:7668256dbe61 111
mbed_official 514:7668256dbe61 112 // configure the pins
mbed_official 514:7668256dbe61 113 pinmap_pinout(sda, PinMap_I2C_SDA);
mbed_official 514:7668256dbe61 114 pinmap_pinout(scl, PinMap_I2C_SCL);
mbed_official 514:7668256dbe61 115
mbed_official 514:7668256dbe61 116 // enable the clock
mbed_official 514:7668256dbe61 117 MXC_CLKMAN->clk_ctrl_6_i2cm = MXC_E_CLKMAN_CLK_SCALE_ENABLED;
mbed_official 514:7668256dbe61 118
mbed_official 514:7668256dbe61 119 // reset module
mbed_official 514:7668256dbe61 120 i2c->ctrl = MXC_F_I2CM_CTRL_MSTR_RESET_EN;
mbed_official 514:7668256dbe61 121 i2c->ctrl = 0;
mbed_official 514:7668256dbe61 122
mbed_official 514:7668256dbe61 123 // set default frequency at 100k
mbed_official 514:7668256dbe61 124 i2c_frequency(obj, 100000);
mbed_official 514:7668256dbe61 125
mbed_official 514:7668256dbe61 126 // set timeout to 255 ms and turn on the auto-stop option
mbed_official 514:7668256dbe61 127 i2c->timeout = (0xFF << MXC_F_I2CM_TIMEOUT_TX_TIMEOUT_POS) | MXC_F_I2CM_TIMEOUT_AUTO_STOP_EN;
mbed_official 514:7668256dbe61 128
mbed_official 514:7668256dbe61 129 // enable tx_fifo and rx_fifo
mbed_official 514:7668256dbe61 130 i2c->ctrl |= (MXC_F_I2CM_CTRL_TX_FIFO_EN | MXC_F_I2CM_CTRL_RX_FIFO_EN);
mbed_official 514:7668256dbe61 131 }
mbed_official 514:7668256dbe61 132
mbed_official 514:7668256dbe61 133 void i2c_frequency(i2c_t *obj, int hz)
mbed_official 514:7668256dbe61 134 {
mbed_official 514:7668256dbe61 135 // compute clock array index
mbed_official 514:7668256dbe61 136 int clki = ((SystemCoreClock + 1500000) / 3000000) - 1;
mbed_official 514:7668256dbe61 137
mbed_official 514:7668256dbe61 138 // get clock divider settings from lookup table
mbed_official 514:7668256dbe61 139 if ((hz < 400000) && (clk_div_table[MXC_E_I2CM_SPEED_100KHZ][clki] > 0)) {
mbed_official 514:7668256dbe61 140 obj->i2c->fs_clk_div = clk_div_table[MXC_E_I2CM_SPEED_100KHZ][clki];
mbed_official 514:7668256dbe61 141 } else if ((hz < 1000000) && (clk_div_table[MXC_E_I2CM_SPEED_400KHZ][clki] > 0)) {
mbed_official 514:7668256dbe61 142 obj->i2c->fs_clk_div = clk_div_table[MXC_E_I2CM_SPEED_400KHZ][clki];
mbed_official 514:7668256dbe61 143 } else if ((hz >= 1000000) && (clk_div_table[MXC_E_I2CM_SPEED_1MHZ][clki] > 0)) {
mbed_official 514:7668256dbe61 144 obj->i2c->hs_clk_div = clk_div_table[MXC_E_I2CM_SPEED_1MHZ][clki];
mbed_official 514:7668256dbe61 145 }
mbed_official 514:7668256dbe61 146 }
mbed_official 514:7668256dbe61 147
mbed_official 514:7668256dbe61 148 static int write_tx_fifo(i2c_t *obj, const uint16_t data)
mbed_official 514:7668256dbe61 149 {
mbed_official 514:7668256dbe61 150 int timeout = MXC_I2CM_TX_TIMEOUT;
mbed_official 514:7668256dbe61 151
mbed_official 514:7668256dbe61 152 while (*obj->txfifo) {
mbed_official 514:7668256dbe61 153 uint32_t intfl = obj->i2c->intfl;
mbed_official 514:7668256dbe61 154 if (intfl & MXC_F_I2CM_INTFL_TX_NACKED) {
mbed_official 514:7668256dbe61 155 return I2C_ERROR_NO_SLAVE;
mbed_official 514:7668256dbe61 156 }
mbed_official 514:7668256dbe61 157 if (!timeout || (intfl & (MXC_F_I2CM_INTFL_TX_TIMEOUT | MXC_F_I2CM_INTFL_TX_LOST_ARBITR))) {
mbed_official 514:7668256dbe61 158 return I2C_ERROR_BUS_BUSY;
mbed_official 514:7668256dbe61 159 }
mbed_official 514:7668256dbe61 160 timeout--;
mbed_official 514:7668256dbe61 161 }
mbed_official 514:7668256dbe61 162 *obj->txfifo = data;
mbed_official 514:7668256dbe61 163
mbed_official 514:7668256dbe61 164 return 0;
mbed_official 514:7668256dbe61 165 }
mbed_official 514:7668256dbe61 166
mbed_official 514:7668256dbe61 167 static int wait_tx_in_progress(i2c_t *obj)
mbed_official 514:7668256dbe61 168 {
mbed_official 514:7668256dbe61 169 int timeout = MXC_I2CM_TX_TIMEOUT;
mbed_official 514:7668256dbe61 170
mbed_official 514:7668256dbe61 171 while ((obj->i2c->trans & MXC_F_I2CM_TRANS_TX_IN_PROGRESS) && --timeout);
mbed_official 514:7668256dbe61 172
mbed_official 514:7668256dbe61 173 uint32_t intfl = obj->i2c->intfl;
mbed_official 514:7668256dbe61 174
mbed_official 514:7668256dbe61 175 if (intfl & MXC_F_I2CM_INTFL_TX_NACKED) {
mbed_official 514:7668256dbe61 176 i2c_reset(obj);
mbed_official 514:7668256dbe61 177 return I2C_ERROR_NO_SLAVE;
mbed_official 514:7668256dbe61 178 }
mbed_official 514:7668256dbe61 179
mbed_official 514:7668256dbe61 180 if (!timeout || (intfl & (MXC_F_I2CM_INTFL_TX_TIMEOUT | MXC_F_I2CM_INTFL_TX_LOST_ARBITR))) {
mbed_official 514:7668256dbe61 181 i2c_reset(obj);
mbed_official 514:7668256dbe61 182 return I2C_ERROR_BUS_BUSY;
mbed_official 514:7668256dbe61 183 }
mbed_official 514:7668256dbe61 184
mbed_official 514:7668256dbe61 185 return 0;
mbed_official 514:7668256dbe61 186 }
mbed_official 514:7668256dbe61 187
mbed_official 514:7668256dbe61 188 int i2c_start(i2c_t *obj)
mbed_official 514:7668256dbe61 189 {
mbed_official 514:7668256dbe61 190 obj->start_pending = 1;
mbed_official 514:7668256dbe61 191 return 0;
mbed_official 514:7668256dbe61 192 }
mbed_official 514:7668256dbe61 193
mbed_official 514:7668256dbe61 194 int i2c_stop(i2c_t *obj)
mbed_official 514:7668256dbe61 195 {
mbed_official 514:7668256dbe61 196 obj->start_pending = 0;
mbed_official 514:7668256dbe61 197 write_tx_fifo(obj, MXC_S_I2CM_TRANS_TAG_STOP);
mbed_official 514:7668256dbe61 198
mbed_official 514:7668256dbe61 199 return wait_tx_in_progress(obj);
mbed_official 514:7668256dbe61 200 }
mbed_official 514:7668256dbe61 201
mbed_official 514:7668256dbe61 202 void i2c_reset(i2c_t *obj)
mbed_official 514:7668256dbe61 203 {
mbed_official 514:7668256dbe61 204 obj->i2c->ctrl = MXC_F_I2CM_CTRL_MSTR_RESET_EN;
mbed_official 514:7668256dbe61 205 obj->i2c->intfl = 0x3FF; // clear all interrupts
mbed_official 514:7668256dbe61 206 obj->i2c->ctrl = MXC_F_I2CM_CTRL_TX_FIFO_EN | MXC_F_I2CM_CTRL_RX_FIFO_EN;
mbed_official 514:7668256dbe61 207 obj->start_pending = 0;
mbed_official 514:7668256dbe61 208 }
mbed_official 514:7668256dbe61 209
mbed_official 514:7668256dbe61 210 int i2c_byte_write(i2c_t *obj, int data)
mbed_official 514:7668256dbe61 211 {
mbed_official 514:7668256dbe61 212 int err;
mbed_official 514:7668256dbe61 213
mbed_official 514:7668256dbe61 214 // clear all interrupts
mbed_official 514:7668256dbe61 215 obj->i2c->intfl = 0x3FF;
mbed_official 514:7668256dbe61 216
mbed_official 514:7668256dbe61 217 if (obj->start_pending) {
mbed_official 514:7668256dbe61 218 obj->start_pending = 0;
mbed_official 514:7668256dbe61 219 data = (data & 0xFF) | MXC_S_I2CM_TRANS_TAG_START;
mbed_official 514:7668256dbe61 220 } else {
mbed_official 514:7668256dbe61 221 data = (data & 0xFF) | MXC_S_I2CM_TRANS_TAG_TXDATA_ACK;
mbed_official 514:7668256dbe61 222 }
mbed_official 514:7668256dbe61 223
mbed_official 514:7668256dbe61 224 if ((err = write_tx_fifo(obj, data)) != 0) {
mbed_official 514:7668256dbe61 225 return err;
mbed_official 514:7668256dbe61 226 }
mbed_official 514:7668256dbe61 227
mbed_official 514:7668256dbe61 228 obj->i2c->trans |= MXC_F_I2CM_TRANS_TX_START;
mbed_official 514:7668256dbe61 229
mbed_official 514:7668256dbe61 230 return 0;
mbed_official 514:7668256dbe61 231 }
mbed_official 514:7668256dbe61 232
mbed_official 514:7668256dbe61 233 int i2c_byte_read(i2c_t *obj, int last)
mbed_official 514:7668256dbe61 234 {
mbed_official 514:7668256dbe61 235 uint16_t fifo_value;
mbed_official 514:7668256dbe61 236 int err;
mbed_official 514:7668256dbe61 237
mbed_official 514:7668256dbe61 238 // clear all interrupts
mbed_official 514:7668256dbe61 239 obj->i2c->intfl = 0x3FF;
mbed_official 514:7668256dbe61 240
mbed_official 514:7668256dbe61 241 if (last) {
mbed_official 514:7668256dbe61 242 fifo_value = MXC_S_I2CM_TRANS_TAG_RXDATA_NACK;
mbed_official 514:7668256dbe61 243 } else {
mbed_official 514:7668256dbe61 244 fifo_value = MXC_S_I2CM_TRANS_TAG_RXDATA_COUNT;
mbed_official 514:7668256dbe61 245 }
mbed_official 514:7668256dbe61 246
mbed_official 514:7668256dbe61 247 if ((err = write_tx_fifo(obj, fifo_value)) != 0) {
mbed_official 514:7668256dbe61 248 return err;
mbed_official 514:7668256dbe61 249 }
mbed_official 514:7668256dbe61 250
mbed_official 514:7668256dbe61 251 obj->i2c->trans |= MXC_F_I2CM_TRANS_TX_START;
mbed_official 514:7668256dbe61 252
mbed_official 514:7668256dbe61 253 int timeout = MXC_I2CM_RX_TIMEOUT;
mbed_official 514:7668256dbe61 254 while (!(obj->i2c->intfl & MXC_F_I2CM_INTFL_RX_FIFO_NOT_EMPTY) &&
mbed_official 514:7668256dbe61 255 (!(obj->i2c->bb & MXC_F_I2CM_BB_RX_FIFO_CNT))) {
mbed_official 514:7668256dbe61 256 if ((--timeout < 0) || !(obj->i2c->trans & MXC_F_I2CM_TRANS_TX_IN_PROGRESS)) {
mbed_official 514:7668256dbe61 257 break;
mbed_official 514:7668256dbe61 258 }
mbed_official 514:7668256dbe61 259 }
mbed_official 514:7668256dbe61 260
mbed_official 514:7668256dbe61 261 if (obj->i2c->intfl & MXC_F_I2CM_INTFL_RX_FIFO_NOT_EMPTY) {
mbed_official 514:7668256dbe61 262 obj->i2c->intfl = MXC_F_I2CM_INTFL_RX_FIFO_NOT_EMPTY;
mbed_official 514:7668256dbe61 263 return *obj->rxfifo;
mbed_official 514:7668256dbe61 264 }
mbed_official 514:7668256dbe61 265
mbed_official 514:7668256dbe61 266 return -1;
mbed_official 514:7668256dbe61 267 }
mbed_official 514:7668256dbe61 268
mbed_official 514:7668256dbe61 269 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
mbed_official 514:7668256dbe61 270 {
mbed_official 514:7668256dbe61 271 int err, retval = 0;
mbed_official 514:7668256dbe61 272 int i;
mbed_official 514:7668256dbe61 273
mbed_official 514:7668256dbe61 274 if (!(obj->stop_pending) && (obj->i2c->trans & MXC_F_I2CM_TRANS_TX_IN_PROGRESS)) {
mbed_official 514:7668256dbe61 275 return 0;
mbed_official 514:7668256dbe61 276 }
mbed_official 514:7668256dbe61 277
mbed_official 514:7668256dbe61 278 // clear all interrupts
mbed_official 514:7668256dbe61 279 obj->i2c->intfl = 0x3FF;
mbed_official 514:7668256dbe61 280
mbed_official 514:7668256dbe61 281 // write the address to the fifo
mbed_official 514:7668256dbe61 282 if ((err = write_tx_fifo(obj, (MXC_S_I2CM_TRANS_TAG_START | address))) != 0) { // start + addr (write)
mbed_official 514:7668256dbe61 283 return err;
mbed_official 514:7668256dbe61 284 }
mbed_official 514:7668256dbe61 285 obj->start_pending = 0;
mbed_official 514:7668256dbe61 286
mbed_official 514:7668256dbe61 287 // start the transaction
mbed_official 514:7668256dbe61 288 obj->i2c->trans |= MXC_F_I2CM_TRANS_TX_START;
mbed_official 514:7668256dbe61 289
mbed_official 514:7668256dbe61 290 // load as much of the cmd into the FIFO as possible
mbed_official 514:7668256dbe61 291 for (i = 0; i < length; i++) {
mbed_official 514:7668256dbe61 292 if ((err = write_tx_fifo(obj, (MXC_S_I2CM_TRANS_TAG_TXDATA_ACK | data[i]))) != 0) { // cmd (expect ACK)
mbed_official 514:7668256dbe61 293 retval = (retval ? retval : err);
mbed_official 514:7668256dbe61 294 break;
mbed_official 514:7668256dbe61 295 }
mbed_official 514:7668256dbe61 296 }
mbed_official 514:7668256dbe61 297
mbed_official 514:7668256dbe61 298 if (stop) {
mbed_official 514:7668256dbe61 299 obj->stop_pending = 0;
mbed_official 514:7668256dbe61 300 if ((err = write_tx_fifo(obj, MXC_S_I2CM_TRANS_TAG_STOP)) != 0) { // stop condition
mbed_official 514:7668256dbe61 301 retval = (retval ? retval : err);
mbed_official 514:7668256dbe61 302 }
mbed_official 514:7668256dbe61 303
mbed_official 514:7668256dbe61 304 if ((err = wait_tx_in_progress(obj)) != 0) {
mbed_official 514:7668256dbe61 305 retval = (retval ? retval : err);
mbed_official 514:7668256dbe61 306 }
mbed_official 514:7668256dbe61 307 } else {
mbed_official 514:7668256dbe61 308 obj->stop_pending = 1;
mbed_official 514:7668256dbe61 309 int timeout = MXC_I2CM_TX_TIMEOUT;
mbed_official 514:7668256dbe61 310 // Wait for TX fifo to be empty
mbed_official 514:7668256dbe61 311 while(!(obj->i2c->intfl & MXC_F_I2CM_INTFL_TX_FIFO_EMPTY) && timeout--) {}
mbed_official 514:7668256dbe61 312 }
mbed_official 514:7668256dbe61 313
mbed_official 514:7668256dbe61 314 if (retval == 0) {
mbed_official 514:7668256dbe61 315 return length;
mbed_official 514:7668256dbe61 316 }
mbed_official 514:7668256dbe61 317
mbed_official 514:7668256dbe61 318 return retval;
mbed_official 514:7668256dbe61 319 }
mbed_official 514:7668256dbe61 320
mbed_official 514:7668256dbe61 321 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
mbed_official 514:7668256dbe61 322 {
mbed_official 514:7668256dbe61 323 int err, retval = 0;
mbed_official 514:7668256dbe61 324 int i = length;
mbed_official 514:7668256dbe61 325 int timeout;
mbed_official 514:7668256dbe61 326
mbed_official 514:7668256dbe61 327 if (!(obj->stop_pending) && (obj->i2c->trans & MXC_F_I2CM_TRANS_TX_IN_PROGRESS)) {
mbed_official 514:7668256dbe61 328 return 0;
mbed_official 514:7668256dbe61 329 }
mbed_official 514:7668256dbe61 330
mbed_official 514:7668256dbe61 331 // clear all interrupts
mbed_official 514:7668256dbe61 332 obj->i2c->intfl = 0x3FF;
mbed_official 514:7668256dbe61 333
mbed_official 514:7668256dbe61 334 // start + addr (read)
mbed_official 514:7668256dbe61 335 if ((retval = write_tx_fifo(obj, (MXC_S_I2CM_TRANS_TAG_START | address | I2C_SLAVE_ADDR_READ_BIT))) != 0) {
mbed_official 514:7668256dbe61 336 goto read_done;
mbed_official 514:7668256dbe61 337 }
mbed_official 514:7668256dbe61 338 obj->start_pending = 0;
mbed_official 514:7668256dbe61 339
mbed_official 514:7668256dbe61 340 while (i > 256) {
mbed_official 514:7668256dbe61 341 if ((retval = write_tx_fifo(obj, (MXC_S_I2CM_TRANS_TAG_RXDATA_COUNT | 255))) != 0) {
mbed_official 514:7668256dbe61 342 goto read_done;
mbed_official 514:7668256dbe61 343 }
mbed_official 514:7668256dbe61 344 i -= 256;
mbed_official 514:7668256dbe61 345 }
mbed_official 514:7668256dbe61 346
mbed_official 514:7668256dbe61 347 if (i > 1) {
mbed_official 514:7668256dbe61 348 if ((retval = write_tx_fifo(obj, (MXC_S_I2CM_TRANS_TAG_RXDATA_COUNT | (i - 2)))) != 0) {
mbed_official 514:7668256dbe61 349 goto read_done;
mbed_official 514:7668256dbe61 350 }
mbed_official 514:7668256dbe61 351 }
mbed_official 514:7668256dbe61 352
mbed_official 514:7668256dbe61 353 // start the transaction
mbed_official 514:7668256dbe61 354 obj->i2c->trans |= MXC_F_I2CM_TRANS_TX_START;
mbed_official 514:7668256dbe61 355
mbed_official 514:7668256dbe61 356 if ((retval = write_tx_fifo(obj, MXC_S_I2CM_TRANS_TAG_RXDATA_NACK)) != 0) { // NACK last data byte
mbed_official 514:7668256dbe61 357 goto read_done;
mbed_official 514:7668256dbe61 358 }
mbed_official 514:7668256dbe61 359
mbed_official 514:7668256dbe61 360 if (stop) {
mbed_official 514:7668256dbe61 361 if ((retval = write_tx_fifo(obj, MXC_S_I2CM_TRANS_TAG_STOP)) != 0) { // stop condition
mbed_official 514:7668256dbe61 362 goto read_done;
mbed_official 514:7668256dbe61 363 }
mbed_official 514:7668256dbe61 364 }
mbed_official 514:7668256dbe61 365
mbed_official 514:7668256dbe61 366 timeout = MXC_I2CM_RX_TIMEOUT;
mbed_official 514:7668256dbe61 367 i = 0;
mbed_official 514:7668256dbe61 368 while (i < length) {
mbed_official 514:7668256dbe61 369 while (!(obj->i2c->intfl & MXC_F_I2CM_INTFL_RX_FIFO_NOT_EMPTY) &&
mbed_official 514:7668256dbe61 370 (!(obj->i2c->bb & MXC_F_I2CM_BB_RX_FIFO_CNT))) {
mbed_official 514:7668256dbe61 371 if ((--timeout < 0) || !(obj->i2c->trans & MXC_F_I2CM_TRANS_TX_IN_PROGRESS)) {
mbed_official 514:7668256dbe61 372 retval = -3;
mbed_official 514:7668256dbe61 373 goto read_done;
mbed_official 514:7668256dbe61 374 }
mbed_official 514:7668256dbe61 375 }
mbed_official 514:7668256dbe61 376
mbed_official 514:7668256dbe61 377 timeout = MXC_I2CM_RX_TIMEOUT;
mbed_official 514:7668256dbe61 378
mbed_official 514:7668256dbe61 379 obj->i2c->intfl = MXC_F_I2CM_INTFL_RX_FIFO_NOT_EMPTY;
mbed_official 514:7668256dbe61 380
mbed_official 514:7668256dbe61 381 uint16_t temp = *obj->rxfifo;
mbed_official 514:7668256dbe61 382
mbed_official 514:7668256dbe61 383 if (temp & MXC_S_I2CM_RSTLS_TAG_EMPTY) {
mbed_official 514:7668256dbe61 384 continue;
mbed_official 514:7668256dbe61 385 }
mbed_official 514:7668256dbe61 386 data[i++] = (uint8_t) temp;
mbed_official 514:7668256dbe61 387 }
mbed_official 514:7668256dbe61 388
mbed_official 514:7668256dbe61 389 read_done:
mbed_official 514:7668256dbe61 390
mbed_official 514:7668256dbe61 391 if (stop) {
mbed_official 514:7668256dbe61 392 obj->stop_pending = 0;
mbed_official 514:7668256dbe61 393 if ((err = wait_tx_in_progress(obj)) != 0) {
mbed_official 514:7668256dbe61 394 retval = (retval ? retval : err);
mbed_official 514:7668256dbe61 395 }
mbed_official 514:7668256dbe61 396 } else {
mbed_official 514:7668256dbe61 397 obj->stop_pending = 1;
mbed_official 514:7668256dbe61 398 }
mbed_official 514:7668256dbe61 399
mbed_official 514:7668256dbe61 400 if (retval == 0) {
mbed_official 514:7668256dbe61 401 return length;
mbed_official 514:7668256dbe61 402 }
mbed_official 514:7668256dbe61 403
mbed_official 514:7668256dbe61 404 return retval;
mbed_official 514:7668256dbe61 405 }