mbed library sources. Supersedes mbed-src.

Fork of mbed-dev by mbed official

Committer:
<>
Date:
Fri Oct 28 11:17:30 2016 +0100
Revision:
149:156823d33999
Child:
153:fa9ff456f731
This updates the lib to the mbed lib v128

NOTE: This release includes a restructuring of the file and directory locations and thus some
include paths in your code may need updating accordingly.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 149:156823d33999 1 /* mbed Microcontroller Library
<> 149:156823d33999 2 * Copyright (c) 2015-2016 Nuvoton
<> 149:156823d33999 3 *
<> 149:156823d33999 4 * Licensed under the Apache License, Version 2.0 (the "License");
<> 149:156823d33999 5 * you may not use this file except in compliance with the License.
<> 149:156823d33999 6 * You may obtain a copy of the License at
<> 149:156823d33999 7 *
<> 149:156823d33999 8 * http://www.apache.org/licenses/LICENSE-2.0
<> 149:156823d33999 9 *
<> 149:156823d33999 10 * Unless required by applicable law or agreed to in writing, software
<> 149:156823d33999 11 * distributed under the License is distributed on an "AS IS" BASIS,
<> 149:156823d33999 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<> 149:156823d33999 13 * See the License for the specific language governing permissions and
<> 149:156823d33999 14 * limitations under the License.
<> 149:156823d33999 15 */
<> 149:156823d33999 16
<> 149:156823d33999 17 #include "i2c_api.h"
<> 149:156823d33999 18
<> 149:156823d33999 19 #if DEVICE_I2C
<> 149:156823d33999 20
<> 149:156823d33999 21 #include "cmsis.h"
<> 149:156823d33999 22 #include "pinmap.h"
<> 149:156823d33999 23 #include "PeripheralPins.h"
<> 149:156823d33999 24 #include "nu_modutil.h"
<> 149:156823d33999 25 #include "nu_miscutil.h"
<> 149:156823d33999 26 #include "nu_bitutil.h"
<> 149:156823d33999 27 #include "critical.h"
<> 149:156823d33999 28
<> 149:156823d33999 29 #define NU_I2C_DEBUG 0
<> 149:156823d33999 30
<> 149:156823d33999 31 #if NU_I2C_DEBUG
<> 149:156823d33999 32 struct i2c_s MY_I2C;
<> 149:156823d33999 33 struct i2c_s MY_I2C_2;
<> 149:156823d33999 34 char MY_I2C_STATUS[64];
<> 149:156823d33999 35 int MY_I2C_STATUS_POS = 0;
<> 149:156823d33999 36 uint32_t MY_I2C_TIMEOUT;
<> 149:156823d33999 37 uint32_t MY_I2C_ELAPSED;
<> 149:156823d33999 38 uint32_t MY_I2C_T1;
<> 149:156823d33999 39 uint32_t MY_I2C_T2;
<> 149:156823d33999 40 #endif
<> 149:156823d33999 41
<> 149:156823d33999 42 struct nu_i2c_var {
<> 149:156823d33999 43 i2c_t * obj;
<> 149:156823d33999 44 void (*vec)(void);
<> 149:156823d33999 45 };
<> 149:156823d33999 46
<> 149:156823d33999 47 static void i2c0_vec(void);
<> 149:156823d33999 48 static void i2c1_vec(void);
<> 149:156823d33999 49 static void i2c2_vec(void);
<> 149:156823d33999 50 static void i2c3_vec(void);
<> 149:156823d33999 51 static void i2c4_vec(void);
<> 149:156823d33999 52 static void i2c_irq(i2c_t *obj);
<> 149:156823d33999 53 static void i2c_fsm_reset(i2c_t *obj, uint32_t i2c_ctl);
<> 149:156823d33999 54
<> 149:156823d33999 55 static struct nu_i2c_var i2c0_var = {
<> 149:156823d33999 56 .obj = NULL,
<> 149:156823d33999 57 .vec = i2c0_vec,
<> 149:156823d33999 58 };
<> 149:156823d33999 59 static struct nu_i2c_var i2c1_var = {
<> 149:156823d33999 60 .obj = NULL,
<> 149:156823d33999 61 .vec = i2c1_vec,
<> 149:156823d33999 62 };
<> 149:156823d33999 63 static struct nu_i2c_var i2c2_var = {
<> 149:156823d33999 64 .obj = NULL,
<> 149:156823d33999 65 .vec = i2c2_vec,
<> 149:156823d33999 66 };
<> 149:156823d33999 67 static struct nu_i2c_var i2c3_var = {
<> 149:156823d33999 68 .obj = NULL,
<> 149:156823d33999 69 .vec = i2c3_vec,
<> 149:156823d33999 70 };
<> 149:156823d33999 71 static struct nu_i2c_var i2c4_var = {
<> 149:156823d33999 72 .obj = NULL,
<> 149:156823d33999 73 .vec = i2c4_vec,
<> 149:156823d33999 74 };
<> 149:156823d33999 75
<> 149:156823d33999 76 static uint32_t i2c_modinit_mask = 0;
<> 149:156823d33999 77
<> 149:156823d33999 78 static const struct nu_modinit_s i2c_modinit_tab[] = {
<> 149:156823d33999 79 {I2C_0, I2C0_MODULE, 0, 0, I2C0_RST, I2C0_IRQn, &i2c0_var},
<> 149:156823d33999 80 {I2C_1, I2C1_MODULE, 0, 0, I2C1_RST, I2C1_IRQn, &i2c1_var},
<> 149:156823d33999 81 {I2C_2, I2C2_MODULE, 0, 0, I2C2_RST, I2C2_IRQn, &i2c2_var},
<> 149:156823d33999 82 {I2C_3, I2C3_MODULE, 0, 0, I2C3_RST, I2C3_IRQn, &i2c3_var},
<> 149:156823d33999 83 {I2C_4, I2C4_MODULE, 0, 0, I2C4_RST, I2C4_IRQn, &i2c4_var},
<> 149:156823d33999 84
<> 149:156823d33999 85 {NC, 0, 0, 0, 0, (IRQn_Type) 0, NULL}
<> 149:156823d33999 86 };
<> 149:156823d33999 87
<> 149:156823d33999 88 static int i2c_do_tran(i2c_t *obj, char *buf, int length, int read, int naklastdata);
<> 149:156823d33999 89 static int i2c_do_write(i2c_t *obj, char data, int naklastdata);
<> 149:156823d33999 90 static int i2c_do_read(i2c_t *obj, char *data, int naklastdata);
<> 149:156823d33999 91 static int i2c_do_trsn(i2c_t *obj, uint32_t i2c_ctl, int sync);
<> 149:156823d33999 92 #define NU_I2C_TIMEOUT_STAT_INT 500000
<> 149:156823d33999 93 #define NU_I2C_TIMEOUT_STOP 500000
<> 149:156823d33999 94 static int i2c_poll_status_timeout(i2c_t *obj, int (*is_status)(i2c_t *obj), uint32_t timeout);
<> 149:156823d33999 95 static int i2c_poll_tran_heatbeat_timeout(i2c_t *obj, uint32_t timeout);
<> 149:156823d33999 96 //static int i2c_is_stat_int(i2c_t *obj);
<> 149:156823d33999 97 //static int i2c_is_stop_det(i2c_t *obj);
<> 149:156823d33999 98 static int i2c_is_trsn_done(i2c_t *obj);
<> 149:156823d33999 99 static int i2c_is_tran_started(i2c_t *obj);
<> 149:156823d33999 100 static int i2c_addr2data(int address, int read);
<> 149:156823d33999 101 #if DEVICE_I2CSLAVE
<> 149:156823d33999 102 // Convert mbed address to BSP address.
<> 149:156823d33999 103 static int i2c_addr2bspaddr(int address);
<> 149:156823d33999 104 #endif // #if DEVICE_I2CSLAVE
<> 149:156823d33999 105 static void i2c_enable_int(i2c_t *obj);
<> 149:156823d33999 106 static void i2c_disable_int(i2c_t *obj);
<> 149:156823d33999 107 static int i2c_set_int(i2c_t *obj, int inten);
<> 149:156823d33999 108
<> 149:156823d33999 109 #if DEVICE_I2C_ASYNCH
<> 149:156823d33999 110 static void i2c_buffer_set(i2c_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length);
<> 149:156823d33999 111 static void i2c_enable_vector_interrupt(i2c_t *obj, uint32_t handler, int enable);
<> 149:156823d33999 112 static void i2c_rollback_vector_interrupt(i2c_t *obj);
<> 149:156823d33999 113 #endif
<> 149:156823d33999 114
<> 149:156823d33999 115 #define TRANCTRL_STARTED (1)
<> 149:156823d33999 116 #define TRANCTRL_NAKLASTDATA (1 << 1)
<> 149:156823d33999 117
<> 149:156823d33999 118 uint32_t us_ticker_read(void);
<> 149:156823d33999 119
<> 149:156823d33999 120 void i2c_init(i2c_t *obj, PinName sda, PinName scl)
<> 149:156823d33999 121 {
<> 149:156823d33999 122 uint32_t i2c_sda = pinmap_peripheral(sda, PinMap_I2C_SDA);
<> 149:156823d33999 123 uint32_t i2c_scl = pinmap_peripheral(scl, PinMap_I2C_SCL);
<> 149:156823d33999 124 obj->i2c.i2c = (I2CName) pinmap_merge(i2c_sda, i2c_scl);
<> 149:156823d33999 125 MBED_ASSERT((int)obj->i2c.i2c != NC);
<> 149:156823d33999 126
<> 149:156823d33999 127 const struct nu_modinit_s *modinit = get_modinit(obj->i2c.i2c, i2c_modinit_tab);
<> 149:156823d33999 128 MBED_ASSERT(modinit != NULL);
<> 149:156823d33999 129 MBED_ASSERT(modinit->modname == obj->i2c.i2c);
<> 149:156823d33999 130
<> 149:156823d33999 131 // Reset this module
<> 149:156823d33999 132 SYS_ResetModule(modinit->rsetidx);
<> 149:156823d33999 133
<> 149:156823d33999 134 // Enable IP clock
<> 149:156823d33999 135 CLK_EnableModuleClock(modinit->clkidx);
<> 149:156823d33999 136
<> 149:156823d33999 137 pinmap_pinout(sda, PinMap_I2C_SDA);
<> 149:156823d33999 138 pinmap_pinout(scl, PinMap_I2C_SCL);
<> 149:156823d33999 139
<> 149:156823d33999 140 #if DEVICE_I2C_ASYNCH
<> 149:156823d33999 141 obj->i2c.dma_usage = DMA_USAGE_NEVER;
<> 149:156823d33999 142 obj->i2c.event = 0;
<> 149:156823d33999 143 obj->i2c.stop = 0;
<> 149:156823d33999 144 obj->i2c.address = 0;
<> 149:156823d33999 145 #endif
<> 149:156823d33999 146
<> 149:156823d33999 147 // NOTE: Setting I2C bus clock to 100 KHz is required. See I2C::I2C in common/I2C.cpp.
<> 149:156823d33999 148 I2C_Open((I2C_T *) NU_MODBASE(obj->i2c.i2c), 100000);
<> 149:156823d33999 149 // NOTE: INTEN bit and FSM control bits (STA, STO, SI, AA) are packed in one register CTL. We cannot control interrupt through
<> 149:156823d33999 150 // INTEN bit without impacting FSM control bits. Use NVIC_EnableIRQ/NVIC_DisableIRQ instead for interrupt control.
<> 149:156823d33999 151 I2C_T *i2c_base = (I2C_T *) NU_MODBASE(obj->i2c.i2c);
<> 149:156823d33999 152 i2c_base->CTL |= (I2C_CTL_INTEN_Msk | I2C_CTL_I2CEN_Msk);
<> 149:156823d33999 153
<> 149:156823d33999 154 // Enable sync-moce vector interrupt.
<> 149:156823d33999 155 struct nu_i2c_var *var = (struct nu_i2c_var *) modinit->var;
<> 149:156823d33999 156 var->obj = obj;
<> 149:156823d33999 157 obj->i2c.tran_ctrl = 0;
<> 149:156823d33999 158 obj->i2c.stop = 0;
<> 149:156823d33999 159 i2c_enable_vector_interrupt(obj, (uint32_t) var->vec, 1);
<> 149:156823d33999 160
<> 149:156823d33999 161 // Mark this module to be inited.
<> 149:156823d33999 162 int i = modinit - i2c_modinit_tab;
<> 149:156823d33999 163 i2c_modinit_mask |= 1 << i;
<> 149:156823d33999 164 }
<> 149:156823d33999 165
<> 149:156823d33999 166 int i2c_start(i2c_t *obj)
<> 149:156823d33999 167 {
<> 149:156823d33999 168 return i2c_do_trsn(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk, 1);
<> 149:156823d33999 169 }
<> 149:156823d33999 170
<> 149:156823d33999 171 int i2c_stop(i2c_t *obj)
<> 149:156823d33999 172 {
<> 149:156823d33999 173 return i2c_do_trsn(obj, I2C_CTL_STO_Msk | I2C_CTL_SI_Msk, 1);
<> 149:156823d33999 174 }
<> 149:156823d33999 175
<> 149:156823d33999 176 void i2c_frequency(i2c_t *obj, int hz)
<> 149:156823d33999 177 {
<> 149:156823d33999 178 I2C_SetBusClockFreq((I2C_T *) NU_MODBASE(obj->i2c.i2c), hz);
<> 149:156823d33999 179 }
<> 149:156823d33999 180
<> 149:156823d33999 181 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
<> 149:156823d33999 182 {
<> 149:156823d33999 183 if (i2c_start(obj)) {
<> 149:156823d33999 184 i2c_stop(obj);
<> 149:156823d33999 185 return I2C_ERROR_BUS_BUSY;
<> 149:156823d33999 186 }
<> 149:156823d33999 187
<> 149:156823d33999 188 if (i2c_do_write(obj, i2c_addr2data(address, 1), 0)) {
<> 149:156823d33999 189 i2c_stop(obj);
<> 149:156823d33999 190 return I2C_ERROR_NO_SLAVE;
<> 149:156823d33999 191 }
<> 149:156823d33999 192
<> 149:156823d33999 193 // Read in bytes
<> 149:156823d33999 194 length = i2c_do_tran(obj, data, length, 1, 1);
<> 149:156823d33999 195
<> 149:156823d33999 196 // If not repeated start, send stop.
<> 149:156823d33999 197 if (stop) {
<> 149:156823d33999 198 i2c_stop(obj);
<> 149:156823d33999 199 }
<> 149:156823d33999 200
<> 149:156823d33999 201 return length;
<> 149:156823d33999 202 }
<> 149:156823d33999 203
<> 149:156823d33999 204 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
<> 149:156823d33999 205 {
<> 149:156823d33999 206 if (i2c_start(obj)) {
<> 149:156823d33999 207 i2c_stop(obj);
<> 149:156823d33999 208 return I2C_ERROR_BUS_BUSY;
<> 149:156823d33999 209 }
<> 149:156823d33999 210
<> 149:156823d33999 211 if (i2c_do_write(obj, i2c_addr2data(address, 0), 0)) {
<> 149:156823d33999 212 i2c_stop(obj);
<> 149:156823d33999 213 return I2C_ERROR_NO_SLAVE;
<> 149:156823d33999 214 }
<> 149:156823d33999 215
<> 149:156823d33999 216 // Write out bytes
<> 149:156823d33999 217 length = i2c_do_tran(obj, (char *) data, length, 0, 1);
<> 149:156823d33999 218
<> 149:156823d33999 219 if (stop) {
<> 149:156823d33999 220 i2c_stop(obj);
<> 149:156823d33999 221 }
<> 149:156823d33999 222
<> 149:156823d33999 223 return length;
<> 149:156823d33999 224 }
<> 149:156823d33999 225
<> 149:156823d33999 226 void i2c_reset(i2c_t *obj)
<> 149:156823d33999 227 {
<> 149:156823d33999 228 i2c_stop(obj);
<> 149:156823d33999 229 }
<> 149:156823d33999 230
<> 149:156823d33999 231 int i2c_byte_read(i2c_t *obj, int last)
<> 149:156823d33999 232 {
<> 149:156823d33999 233 char data = 0;
<> 149:156823d33999 234
<> 149:156823d33999 235 i2c_do_read(obj, &data, last);
<> 149:156823d33999 236 return data;
<> 149:156823d33999 237 }
<> 149:156823d33999 238
<> 149:156823d33999 239 int i2c_byte_write(i2c_t *obj, int data)
<> 149:156823d33999 240 {
<> 149:156823d33999 241 return i2c_do_write(obj, (data & 0xFF), 0);
<> 149:156823d33999 242 }
<> 149:156823d33999 243
<> 149:156823d33999 244 #if DEVICE_I2CSLAVE
<> 149:156823d33999 245
<> 149:156823d33999 246 // See I2CSlave.h
<> 149:156823d33999 247 #define NoData 0 // the slave has not been addressed
<> 149:156823d33999 248 #define ReadAddressed 1 // the master has requested a read from this slave (slave = transmitter)
<> 149:156823d33999 249 #define WriteGeneral 2 // the master is writing to all slave
<> 149:156823d33999 250 #define WriteAddressed 3 // the master is writing to this slave (slave = receiver)
<> 149:156823d33999 251
<> 149:156823d33999 252 void i2c_slave_mode(i2c_t *obj, int enable_slave)
<> 149:156823d33999 253 {
<> 149:156823d33999 254 I2C_T *i2c_base = (I2C_T *) NU_MODBASE(obj->i2c.i2c);
<> 149:156823d33999 255
<> 149:156823d33999 256 i2c_disable_int(obj);
<> 149:156823d33999 257
<> 149:156823d33999 258 obj->i2c.slaveaddr_state = NoData;
<> 149:156823d33999 259
<> 149:156823d33999 260 // Switch to not addressed mode
<> 149:156823d33999 261 I2C_SET_CONTROL_REG(i2c_base, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk);
<> 149:156823d33999 262
<> 149:156823d33999 263 i2c_enable_int(obj);
<> 149:156823d33999 264 }
<> 149:156823d33999 265
<> 149:156823d33999 266 int i2c_slave_receive(i2c_t *obj)
<> 149:156823d33999 267 {
<> 149:156823d33999 268 int slaveaddr_state;
<> 149:156823d33999 269
<> 149:156823d33999 270 i2c_disable_int(obj);
<> 149:156823d33999 271 slaveaddr_state = obj->i2c.slaveaddr_state;
<> 149:156823d33999 272 i2c_enable_int(obj);
<> 149:156823d33999 273
<> 149:156823d33999 274 return slaveaddr_state;
<> 149:156823d33999 275 }
<> 149:156823d33999 276
<> 149:156823d33999 277 int i2c_slave_read(i2c_t *obj, char *data, int length)
<> 149:156823d33999 278 {
<> 149:156823d33999 279 return i2c_do_tran(obj, data, length, 1, 1);
<> 149:156823d33999 280 }
<> 149:156823d33999 281
<> 149:156823d33999 282 int i2c_slave_write(i2c_t *obj, const char *data, int length)
<> 149:156823d33999 283 {
<> 149:156823d33999 284 return i2c_do_tran(obj, (char *) data, length, 0, 1);
<> 149:156823d33999 285 }
<> 149:156823d33999 286
<> 149:156823d33999 287 void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask)
<> 149:156823d33999 288 {
<> 149:156823d33999 289 I2C_T *i2c_base = (I2C_T *) NU_MODBASE(obj->i2c.i2c);
<> 149:156823d33999 290
<> 149:156823d33999 291 i2c_disable_int(obj);
<> 149:156823d33999 292
<> 149:156823d33999 293 I2C_SetSlaveAddr(i2c_base, 0, i2c_addr2bspaddr(address), I2C_GCMODE_ENABLE);
<> 149:156823d33999 294
<> 149:156823d33999 295 i2c_enable_int(obj);
<> 149:156823d33999 296 }
<> 149:156823d33999 297
<> 149:156823d33999 298 static int i2c_addr2bspaddr(int address)
<> 149:156823d33999 299 {
<> 149:156823d33999 300 return (address >> 1);
<> 149:156823d33999 301 }
<> 149:156823d33999 302
<> 149:156823d33999 303 #endif // #if DEVICE_I2CSLAVE
<> 149:156823d33999 304
<> 149:156823d33999 305 static void i2c_enable_int(i2c_t *obj)
<> 149:156823d33999 306 {
<> 149:156823d33999 307 const struct nu_modinit_s *modinit = get_modinit(obj->i2c.i2c, i2c_modinit_tab);
<> 149:156823d33999 308
<> 149:156823d33999 309 core_util_critical_section_enter();
<> 149:156823d33999 310
<> 149:156823d33999 311 // Enable I2C interrupt
<> 149:156823d33999 312 NVIC_EnableIRQ(modinit->irq_n);
<> 149:156823d33999 313 obj->i2c.inten = 1;
<> 149:156823d33999 314
<> 149:156823d33999 315 core_util_critical_section_exit();
<> 149:156823d33999 316 }
<> 149:156823d33999 317
<> 149:156823d33999 318 static void i2c_disable_int(i2c_t *obj)
<> 149:156823d33999 319 {
<> 149:156823d33999 320 const struct nu_modinit_s *modinit = get_modinit(obj->i2c.i2c, i2c_modinit_tab);
<> 149:156823d33999 321
<> 149:156823d33999 322 core_util_critical_section_enter();
<> 149:156823d33999 323
<> 149:156823d33999 324 // Disable I2C interrupt
<> 149:156823d33999 325 NVIC_DisableIRQ(modinit->irq_n);
<> 149:156823d33999 326 obj->i2c.inten = 0;
<> 149:156823d33999 327
<> 149:156823d33999 328 core_util_critical_section_exit();
<> 149:156823d33999 329 }
<> 149:156823d33999 330
<> 149:156823d33999 331 static int i2c_set_int(i2c_t *obj, int inten)
<> 149:156823d33999 332 {
<> 149:156823d33999 333 int inten_back;
<> 149:156823d33999 334
<> 149:156823d33999 335 core_util_critical_section_enter();
<> 149:156823d33999 336
<> 149:156823d33999 337 inten_back = obj->i2c.inten;
<> 149:156823d33999 338
<> 149:156823d33999 339 core_util_critical_section_exit();
<> 149:156823d33999 340
<> 149:156823d33999 341 if (inten) {
<> 149:156823d33999 342 i2c_enable_int(obj);
<> 149:156823d33999 343 }
<> 149:156823d33999 344 else {
<> 149:156823d33999 345 i2c_disable_int(obj);
<> 149:156823d33999 346 }
<> 149:156823d33999 347
<> 149:156823d33999 348 return inten_back;
<> 149:156823d33999 349 }
<> 149:156823d33999 350
<> 149:156823d33999 351 int i2c_allow_powerdown(void)
<> 149:156823d33999 352 {
<> 149:156823d33999 353 uint32_t modinit_mask = i2c_modinit_mask;
<> 149:156823d33999 354 while (modinit_mask) {
<> 149:156823d33999 355 int i2c_idx = nu_ctz(modinit_mask);
<> 149:156823d33999 356 const struct nu_modinit_s *modinit = i2c_modinit_tab + i2c_idx;
<> 149:156823d33999 357 struct nu_i2c_var *var = (struct nu_i2c_var *) modinit->var;
<> 149:156823d33999 358 if (var->obj) {
<> 149:156823d33999 359 // Disallow entering power-down mode if I2C transfer is enabled.
<> 149:156823d33999 360 if (i2c_active(var->obj)) {
<> 149:156823d33999 361 return 0;
<> 149:156823d33999 362 }
<> 149:156823d33999 363 }
<> 149:156823d33999 364 modinit_mask &= ~(1 << i2c_idx);
<> 149:156823d33999 365 }
<> 149:156823d33999 366
<> 149:156823d33999 367 return 1;
<> 149:156823d33999 368 }
<> 149:156823d33999 369
<> 149:156823d33999 370 static int i2c_do_tran(i2c_t *obj, char *buf, int length, int read, int naklastdata)
<> 149:156823d33999 371 {
<> 149:156823d33999 372 int tran_len = 0;
<> 149:156823d33999 373
<> 149:156823d33999 374 i2c_disable_int(obj);
<> 149:156823d33999 375 obj->i2c.tran_ctrl = naklastdata ? (TRANCTRL_STARTED | TRANCTRL_NAKLASTDATA) : TRANCTRL_STARTED;
<> 149:156823d33999 376 obj->i2c.tran_beg = buf;
<> 149:156823d33999 377 obj->i2c.tran_pos = buf;
<> 149:156823d33999 378 obj->i2c.tran_end = buf + length;
<> 149:156823d33999 379 i2c_enable_int(obj);
<> 149:156823d33999 380
<> 149:156823d33999 381 if (i2c_poll_tran_heatbeat_timeout(obj, NU_I2C_TIMEOUT_STAT_INT)) {
<> 149:156823d33999 382 #if NU_I2C_DEBUG
<> 149:156823d33999 383 MY_I2C_2 = obj->i2c;
<> 149:156823d33999 384 while (1);
<> 149:156823d33999 385 #endif
<> 149:156823d33999 386 }
<> 149:156823d33999 387 else {
<> 149:156823d33999 388 i2c_disable_int(obj);
<> 149:156823d33999 389 obj->i2c.tran_ctrl = 0;
<> 149:156823d33999 390 tran_len = obj->i2c.tran_pos - obj->i2c.tran_beg;
<> 149:156823d33999 391 obj->i2c.tran_beg = NULL;
<> 149:156823d33999 392 obj->i2c.tran_pos = NULL;
<> 149:156823d33999 393 obj->i2c.tran_end = NULL;
<> 149:156823d33999 394 i2c_enable_int(obj);
<> 149:156823d33999 395 }
<> 149:156823d33999 396
<> 149:156823d33999 397 return tran_len;
<> 149:156823d33999 398 }
<> 149:156823d33999 399
<> 149:156823d33999 400 static int i2c_do_write(i2c_t *obj, char data, int naklastdata)
<> 149:156823d33999 401 {
<> 149:156823d33999 402 char data_[1];
<> 149:156823d33999 403 data_[0] = data;
<> 149:156823d33999 404 return i2c_do_tran(obj, data_, 1, 0, naklastdata) == 1 ? 0 : I2C_ERROR_BUS_BUSY;
<> 149:156823d33999 405 }
<> 149:156823d33999 406
<> 149:156823d33999 407 static int i2c_do_read(i2c_t *obj, char *data, int naklastdata)
<> 149:156823d33999 408 {
<> 149:156823d33999 409 return i2c_do_tran(obj, data, 1, 1, naklastdata) == 1 ? 0 : I2C_ERROR_BUS_BUSY;
<> 149:156823d33999 410 }
<> 149:156823d33999 411
<> 149:156823d33999 412 static int i2c_do_trsn(i2c_t *obj, uint32_t i2c_ctl, int sync)
<> 149:156823d33999 413 {
<> 149:156823d33999 414 I2C_T *i2c_base = (I2C_T *) NU_MODBASE(obj->i2c.i2c);
<> 149:156823d33999 415 int err = 0;
<> 149:156823d33999 416
<> 149:156823d33999 417 i2c_disable_int(obj);
<> 149:156823d33999 418
<> 149:156823d33999 419 if (i2c_poll_status_timeout(obj, i2c_is_trsn_done, NU_I2C_TIMEOUT_STAT_INT)) {
<> 149:156823d33999 420 err = I2C_ERROR_BUS_BUSY;
<> 149:156823d33999 421 #if NU_I2C_DEBUG
<> 149:156823d33999 422 MY_I2C_2 = obj->i2c;
<> 149:156823d33999 423 while (1);
<> 149:156823d33999 424 #endif
<> 149:156823d33999 425 }
<> 149:156823d33999 426 else {
<> 149:156823d33999 427 #if 1
<> 149:156823d33999 428 // NOTE: Avoid duplicate Start/Stop. Otherwise, we may meet strange error.
<> 149:156823d33999 429 uint32_t status = I2C_GET_STATUS(i2c_base);
<> 149:156823d33999 430
<> 149:156823d33999 431 switch (status) {
<> 149:156823d33999 432 case 0x08: // Start
<> 149:156823d33999 433 case 0x10: // Master Repeat Start
<> 149:156823d33999 434 if (i2c_ctl & I2C_CTL_STA_Msk) {
<> 149:156823d33999 435 return 0;
<> 149:156823d33999 436 }
<> 149:156823d33999 437 else {
<> 149:156823d33999 438 break;
<> 149:156823d33999 439 }
<> 149:156823d33999 440 case 0xF8: // Bus Released
<> 149:156823d33999 441 if (i2c_ctl & (I2C_CTL_STA_Msk | I2C_CTL_STO_Msk) == I2C_CTL_STO_Msk) {
<> 149:156823d33999 442 return 0;
<> 149:156823d33999 443 }
<> 149:156823d33999 444 else {
<> 149:156823d33999 445 break;
<> 149:156823d33999 446 }
<> 149:156823d33999 447 }
<> 149:156823d33999 448 #endif
<> 149:156823d33999 449 I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
<> 149:156823d33999 450 if (sync && i2c_poll_status_timeout(obj, i2c_is_trsn_done, NU_I2C_TIMEOUT_STAT_INT)) {
<> 149:156823d33999 451 err = I2C_ERROR_BUS_BUSY;
<> 149:156823d33999 452 #if NU_I2C_DEBUG
<> 149:156823d33999 453 MY_I2C_2 = obj->i2c;
<> 149:156823d33999 454 while (1);
<> 149:156823d33999 455 #endif
<> 149:156823d33999 456 }
<> 149:156823d33999 457 }
<> 149:156823d33999 458
<> 149:156823d33999 459 i2c_enable_int(obj);
<> 149:156823d33999 460
<> 149:156823d33999 461 return err;
<> 149:156823d33999 462 }
<> 149:156823d33999 463
<> 149:156823d33999 464 static int i2c_poll_status_timeout(i2c_t *obj, int (*is_status)(i2c_t *obj), uint32_t timeout)
<> 149:156823d33999 465 {
<> 149:156823d33999 466 uint32_t t1, t2, elapsed = 0;
<> 149:156823d33999 467 int status_assert = 0;
<> 149:156823d33999 468
<> 149:156823d33999 469 t1 = us_ticker_read();
<> 149:156823d33999 470 while (1) {
<> 149:156823d33999 471 status_assert = is_status(obj);
<> 149:156823d33999 472 if (status_assert) {
<> 149:156823d33999 473 break;
<> 149:156823d33999 474 }
<> 149:156823d33999 475
<> 149:156823d33999 476 t2 = us_ticker_read();
<> 149:156823d33999 477 elapsed = (t2 > t1) ? (t2 - t1) : ((uint64_t) t2 + 0xFFFFFFFF - t1 + 1);
<> 149:156823d33999 478 if (elapsed >= timeout) {
<> 149:156823d33999 479 #if NU_I2C_DEBUG
<> 149:156823d33999 480 MY_I2C_T1 = t1;
<> 149:156823d33999 481 MY_I2C_T2 = t2;
<> 149:156823d33999 482 MY_I2C_ELAPSED = elapsed;
<> 149:156823d33999 483 MY_I2C_TIMEOUT = timeout;
<> 149:156823d33999 484 MY_I2C_2 = obj->i2c;
<> 149:156823d33999 485 while (1);
<> 149:156823d33999 486 #endif
<> 149:156823d33999 487 break;
<> 149:156823d33999 488 }
<> 149:156823d33999 489 }
<> 149:156823d33999 490
<> 149:156823d33999 491 return (elapsed >= timeout);
<> 149:156823d33999 492 }
<> 149:156823d33999 493
<> 149:156823d33999 494 static int i2c_poll_tran_heatbeat_timeout(i2c_t *obj, uint32_t timeout)
<> 149:156823d33999 495 {
<> 149:156823d33999 496 uint32_t t1, t2, elapsed = 0;
<> 149:156823d33999 497 int tran_started;
<> 149:156823d33999 498 char *tran_pos = NULL;
<> 149:156823d33999 499 char *tran_pos2 = NULL;
<> 149:156823d33999 500
<> 149:156823d33999 501 i2c_disable_int(obj);
<> 149:156823d33999 502 tran_pos = obj->i2c.tran_pos;
<> 149:156823d33999 503 i2c_enable_int(obj);
<> 149:156823d33999 504 t1 = us_ticker_read();
<> 149:156823d33999 505 while (1) {
<> 149:156823d33999 506 i2c_disable_int(obj);
<> 149:156823d33999 507 tran_started = i2c_is_tran_started(obj);
<> 149:156823d33999 508 i2c_enable_int(obj);
<> 149:156823d33999 509 if (! tran_started) { // Transfer completed or stopped
<> 149:156823d33999 510 break;
<> 149:156823d33999 511 }
<> 149:156823d33999 512
<> 149:156823d33999 513 i2c_disable_int(obj);
<> 149:156823d33999 514 tran_pos2 = obj->i2c.tran_pos;
<> 149:156823d33999 515 i2c_enable_int(obj);
<> 149:156823d33999 516 t2 = us_ticker_read();
<> 149:156823d33999 517 if (tran_pos2 != tran_pos) { // Transfer on-going
<> 149:156823d33999 518 t1 = t2;
<> 149:156823d33999 519 tran_pos = tran_pos2;
<> 149:156823d33999 520 continue;
<> 149:156823d33999 521 }
<> 149:156823d33999 522
<> 149:156823d33999 523 elapsed = (t2 > t1) ? (t2 - t1) : ((uint64_t) t2 + 0xFFFFFFFF - t1 + 1);
<> 149:156823d33999 524 if (elapsed >= timeout) { // Transfer idle
<> 149:156823d33999 525 #if NU_I2C_DEBUG
<> 149:156823d33999 526 MY_I2C = obj->i2c;
<> 149:156823d33999 527 MY_I2C_T1 = t1;
<> 149:156823d33999 528 MY_I2C_T2 = t2;
<> 149:156823d33999 529 MY_I2C_ELAPSED = elapsed;
<> 149:156823d33999 530 MY_I2C_TIMEOUT = timeout;
<> 149:156823d33999 531 MY_I2C_2 = obj->i2c;
<> 149:156823d33999 532 while (1);
<> 149:156823d33999 533 #endif
<> 149:156823d33999 534 break;
<> 149:156823d33999 535 }
<> 149:156823d33999 536 }
<> 149:156823d33999 537
<> 149:156823d33999 538 return (elapsed >= timeout);
<> 149:156823d33999 539 }
<> 149:156823d33999 540
<> 149:156823d33999 541 #if 0
<> 149:156823d33999 542 static int i2c_is_stat_int(i2c_t *obj)
<> 149:156823d33999 543 {
<> 149:156823d33999 544 I2C_T *i2c_base = (I2C_T *) NU_MODBASE(obj->i2c.i2c);
<> 149:156823d33999 545
<> 149:156823d33999 546 return !! (i2c_base->CTL & I2C_CTL_SI_Msk);
<> 149:156823d33999 547 }
<> 149:156823d33999 548
<> 149:156823d33999 549
<> 149:156823d33999 550 static int i2c_is_stop_det(i2c_t *obj)
<> 149:156823d33999 551 {
<> 149:156823d33999 552 I2C_T *i2c_base = (I2C_T *) NU_MODBASE(obj->i2c.i2c);
<> 149:156823d33999 553
<> 149:156823d33999 554 return ! (i2c_base->CTL & I2C_CTL_STO_Msk);
<> 149:156823d33999 555 }
<> 149:156823d33999 556 #endif
<> 149:156823d33999 557
<> 149:156823d33999 558 static int i2c_is_trsn_done(i2c_t *obj)
<> 149:156823d33999 559 {
<> 149:156823d33999 560 I2C_T *i2c_base = (I2C_T *) NU_MODBASE(obj->i2c.i2c);
<> 149:156823d33999 561 int i2c_int;
<> 149:156823d33999 562 uint32_t status;
<> 149:156823d33999 563 int inten_back;
<> 149:156823d33999 564
<> 149:156823d33999 565 inten_back = i2c_set_int(obj, 0);
<> 149:156823d33999 566 i2c_int = !! (i2c_base->CTL & I2C_CTL_SI_Msk);
<> 149:156823d33999 567 status = I2C_GET_STATUS(i2c_base);
<> 149:156823d33999 568 i2c_set_int(obj, inten_back);
<> 149:156823d33999 569
<> 149:156823d33999 570 return (i2c_int || status == 0xF8);
<> 149:156823d33999 571 }
<> 149:156823d33999 572
<> 149:156823d33999 573 static int i2c_is_tran_started(i2c_t *obj)
<> 149:156823d33999 574 {
<> 149:156823d33999 575 int started;
<> 149:156823d33999 576 int inten_back;
<> 149:156823d33999 577
<> 149:156823d33999 578 inten_back = i2c_set_int(obj, 0);
<> 149:156823d33999 579 started = !! (obj->i2c.tran_ctrl & TRANCTRL_STARTED);
<> 149:156823d33999 580 i2c_set_int(obj, inten_back);
<> 149:156823d33999 581
<> 149:156823d33999 582 return started;
<> 149:156823d33999 583 }
<> 149:156823d33999 584
<> 149:156823d33999 585 static int i2c_addr2data(int address, int read)
<> 149:156823d33999 586 {
<> 149:156823d33999 587 return read ? (address | 1) : (address & 0xFE);
<> 149:156823d33999 588 }
<> 149:156823d33999 589
<> 149:156823d33999 590 static void i2c0_vec(void)
<> 149:156823d33999 591 {
<> 149:156823d33999 592 i2c_irq(i2c0_var.obj);
<> 149:156823d33999 593 }
<> 149:156823d33999 594 static void i2c1_vec(void)
<> 149:156823d33999 595 {
<> 149:156823d33999 596 i2c_irq(i2c1_var.obj);
<> 149:156823d33999 597 }
<> 149:156823d33999 598 static void i2c2_vec(void)
<> 149:156823d33999 599 {
<> 149:156823d33999 600 i2c_irq(i2c2_var.obj);
<> 149:156823d33999 601 }
<> 149:156823d33999 602 static void i2c3_vec(void)
<> 149:156823d33999 603 {
<> 149:156823d33999 604 i2c_irq(i2c3_var.obj);
<> 149:156823d33999 605 }
<> 149:156823d33999 606 static void i2c4_vec(void)
<> 149:156823d33999 607 {
<> 149:156823d33999 608 i2c_irq(i2c4_var.obj);
<> 149:156823d33999 609 }
<> 149:156823d33999 610
<> 149:156823d33999 611 static void i2c_irq(i2c_t *obj)
<> 149:156823d33999 612 {
<> 149:156823d33999 613 I2C_T *i2c_base = (I2C_T *) NU_MODBASE(obj->i2c.i2c);
<> 149:156823d33999 614 uint32_t status;
<> 149:156823d33999 615
<> 149:156823d33999 616 if (I2C_GET_TIMEOUT_FLAG(i2c_base)) {
<> 149:156823d33999 617 I2C_ClearTimeoutFlag(i2c_base);
<> 149:156823d33999 618 return;
<> 149:156823d33999 619 }
<> 149:156823d33999 620
<> 149:156823d33999 621 status = I2C_GET_STATUS(i2c_base);
<> 149:156823d33999 622 #if NU_I2C_DEBUG
<> 149:156823d33999 623 if (MY_I2C_STATUS_POS < (sizeof (MY_I2C_STATUS) / sizeof (MY_I2C_STATUS[0]))) {
<> 149:156823d33999 624 MY_I2C_STATUS[MY_I2C_STATUS_POS ++] = status;
<> 149:156823d33999 625 }
<> 149:156823d33999 626 else {
<> 149:156823d33999 627 memset(MY_I2C_STATUS, 0x00, sizeof (MY_I2C_STATUS));
<> 149:156823d33999 628 MY_I2C_STATUS_POS = 0;
<> 149:156823d33999 629 }
<> 149:156823d33999 630 #endif
<> 149:156823d33999 631
<> 149:156823d33999 632 switch (status) {
<> 149:156823d33999 633 // Master Transmit
<> 149:156823d33999 634 case 0x28: // Master Transmit Data ACK
<> 149:156823d33999 635 case 0x18: // Master Transmit Address ACK
<> 149:156823d33999 636 case 0x08: // Start
<> 149:156823d33999 637 case 0x10: // Master Repeat Start
<> 149:156823d33999 638 if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
<> 149:156823d33999 639 if (obj->i2c.tran_pos < obj->i2c.tran_end) {
<> 149:156823d33999 640 I2C_SET_DATA(i2c_base, *obj->i2c.tran_pos ++);
<> 149:156823d33999 641 I2C_SET_CONTROL_REG(i2c_base, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk);
<> 149:156823d33999 642 }
<> 149:156823d33999 643 else {
<> 149:156823d33999 644 if (status == 0x18) {
<> 149:156823d33999 645 obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
<> 149:156823d33999 646 i2c_disable_int(obj);
<> 149:156823d33999 647 break;
<> 149:156823d33999 648 }
<> 149:156823d33999 649 // Go Master Repeat Start
<> 149:156823d33999 650 i2c_fsm_reset(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk);
<> 149:156823d33999 651 }
<> 149:156823d33999 652 }
<> 149:156823d33999 653 else {
<> 149:156823d33999 654 i2c_disable_int(obj);
<> 149:156823d33999 655 }
<> 149:156823d33999 656 break;
<> 149:156823d33999 657 case 0x30: // Master Transmit Data NACK
<> 149:156823d33999 658 case 0x20: // Master Transmit Address NACK
<> 149:156823d33999 659 // Go Master Repeat Start
<> 149:156823d33999 660 i2c_fsm_reset(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk);
<> 149:156823d33999 661 break;
<> 149:156823d33999 662 case 0x38: // Master Arbitration Lost
<> 149:156823d33999 663 i2c_fsm_reset(obj, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk);
<> 149:156823d33999 664 break;
<> 149:156823d33999 665
<> 149:156823d33999 666 case 0x48: // Master Receive Address NACK
<> 149:156823d33999 667 // Go Master Stop.
<> 149:156823d33999 668 // Go Master Repeat Start
<> 149:156823d33999 669 i2c_fsm_reset(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk);
<> 149:156823d33999 670 break;
<> 149:156823d33999 671 case 0x40: // Master Receive Address ACK
<> 149:156823d33999 672 case 0x50: // Master Receive Data ACK
<> 149:156823d33999 673 case 0x58: // Master Receive Data NACK
<> 149:156823d33999 674 if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
<> 149:156823d33999 675 if (obj->i2c.tran_pos < obj->i2c.tran_end) {
<> 149:156823d33999 676 if (status == 0x50 || status == 0x58) {
<> 149:156823d33999 677 *obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
<> 149:156823d33999 678 }
<> 149:156823d33999 679
<> 149:156823d33999 680 if (status == 0x58) {
<> 149:156823d33999 681 #if NU_I2C_DEBUG
<> 149:156823d33999 682 if (obj->i2c.tran_pos != obj->i2c.tran_end) {
<> 149:156823d33999 683 MY_I2C = obj->i2c;
<> 149:156823d33999 684 while (1);
<> 149:156823d33999 685 }
<> 149:156823d33999 686 #endif
<> 149:156823d33999 687 // Go Master Repeat Start
<> 149:156823d33999 688 i2c_fsm_reset(obj, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk);
<> 149:156823d33999 689 }
<> 149:156823d33999 690 else {
<> 149:156823d33999 691 uint32_t i2c_ctl = I2C_CTL_SI_Msk | I2C_CTL_AA_Msk;
<> 149:156823d33999 692 if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
<> 149:156823d33999 693 obj->i2c.tran_ctrl & TRANCTRL_NAKLASTDATA) {
<> 149:156823d33999 694 // Last data
<> 149:156823d33999 695 i2c_ctl &= ~I2C_CTL_AA_Msk;
<> 149:156823d33999 696 }
<> 149:156823d33999 697 I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
<> 149:156823d33999 698 }
<> 149:156823d33999 699 }
<> 149:156823d33999 700 else {
<> 149:156823d33999 701 obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
<> 149:156823d33999 702 i2c_disable_int(obj);
<> 149:156823d33999 703 break;
<> 149:156823d33999 704 }
<> 149:156823d33999 705 }
<> 149:156823d33999 706 else {
<> 149:156823d33999 707 i2c_disable_int(obj);
<> 149:156823d33999 708 }
<> 149:156823d33999 709 break;
<> 149:156823d33999 710
<> 149:156823d33999 711 //case 0x00: // Bus error
<> 149:156823d33999 712
<> 149:156823d33999 713 // Slave Transmit
<> 149:156823d33999 714 case 0xB8: // Slave Transmit Data ACK
<> 149:156823d33999 715 case 0xA8: // Slave Transmit Address ACK
<> 149:156823d33999 716 case 0xB0: // Slave Transmit Arbitration Lost
<> 149:156823d33999 717 if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
<> 149:156823d33999 718 if (obj->i2c.tran_pos < obj->i2c.tran_end) {
<> 149:156823d33999 719 uint32_t i2c_ctl = I2C_CTL_SI_Msk | I2C_CTL_AA_Msk;
<> 149:156823d33999 720
<> 149:156823d33999 721 I2C_SET_DATA(i2c_base, *obj->i2c.tran_pos ++);
<> 149:156823d33999 722 if (obj->i2c.tran_pos == obj->i2c.tran_end &&
<> 149:156823d33999 723 obj->i2c.tran_ctrl & TRANCTRL_NAKLASTDATA) {
<> 149:156823d33999 724 // Last data
<> 149:156823d33999 725 i2c_ctl &= ~I2C_CTL_AA_Msk;
<> 149:156823d33999 726 }
<> 149:156823d33999 727 I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
<> 149:156823d33999 728 }
<> 149:156823d33999 729 else {
<> 149:156823d33999 730 obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
<> 149:156823d33999 731 i2c_disable_int(obj);
<> 149:156823d33999 732 break;
<> 149:156823d33999 733 }
<> 149:156823d33999 734 }
<> 149:156823d33999 735 else {
<> 149:156823d33999 736 i2c_disable_int(obj);
<> 149:156823d33999 737 }
<> 149:156823d33999 738 obj->i2c.slaveaddr_state = ReadAddressed;
<> 149:156823d33999 739 break;
<> 149:156823d33999 740 //case 0xA0: // Slave Transmit Repeat Start or Stop
<> 149:156823d33999 741 case 0xC0: // Slave Transmit Data NACK
<> 149:156823d33999 742 case 0xC8: // Slave Transmit Last Data ACK
<> 149:156823d33999 743 obj->i2c.slaveaddr_state = NoData;
<> 149:156823d33999 744 i2c_fsm_reset(obj, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk);
<> 149:156823d33999 745 break;
<> 149:156823d33999 746
<> 149:156823d33999 747 // Slave Receive
<> 149:156823d33999 748 case 0x80: // Slave Receive Data ACK
<> 149:156823d33999 749 case 0x88: // Slave Receive Data NACK
<> 149:156823d33999 750 case 0x60: // Slave Receive Address ACK
<> 149:156823d33999 751 case 0x68: // Slave Receive Arbitration Lost
<> 149:156823d33999 752 obj->i2c.slaveaddr_state = WriteAddressed;
<> 149:156823d33999 753 if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
<> 149:156823d33999 754 if (obj->i2c.tran_pos < obj->i2c.tran_end) {
<> 149:156823d33999 755 if (status == 0x80 || status == 0x88) {
<> 149:156823d33999 756 *obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
<> 149:156823d33999 757 }
<> 149:156823d33999 758
<> 149:156823d33999 759 if (status == 0x88) {
<> 149:156823d33999 760 #if NU_I2C_DEBUG
<> 149:156823d33999 761 if (obj->i2c.tran_pos != obj->i2c.tran_end) {
<> 149:156823d33999 762 MY_I2C = obj->i2c;
<> 149:156823d33999 763 while (1);
<> 149:156823d33999 764 }
<> 149:156823d33999 765 #endif
<> 149:156823d33999 766 obj->i2c.slaveaddr_state = NoData;
<> 149:156823d33999 767 i2c_fsm_reset(obj, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk);
<> 149:156823d33999 768 }
<> 149:156823d33999 769 else {
<> 149:156823d33999 770 uint32_t i2c_ctl = I2C_CTL_SI_Msk | I2C_CTL_AA_Msk;
<> 149:156823d33999 771 if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
<> 149:156823d33999 772 obj->i2c.tran_ctrl & TRANCTRL_NAKLASTDATA) {
<> 149:156823d33999 773 // Last data
<> 149:156823d33999 774 i2c_ctl &= ~I2C_CTL_AA_Msk;
<> 149:156823d33999 775 }
<> 149:156823d33999 776 I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
<> 149:156823d33999 777 }
<> 149:156823d33999 778 }
<> 149:156823d33999 779 else {
<> 149:156823d33999 780 obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
<> 149:156823d33999 781 i2c_disable_int(obj);
<> 149:156823d33999 782 break;
<> 149:156823d33999 783 }
<> 149:156823d33999 784 }
<> 149:156823d33999 785 else {
<> 149:156823d33999 786 i2c_disable_int(obj);
<> 149:156823d33999 787 }
<> 149:156823d33999 788 break;
<> 149:156823d33999 789 //case 0xA0: // Slave Receive Repeat Start or Stop
<> 149:156823d33999 790
<> 149:156823d33999 791 // GC mode
<> 149:156823d33999 792 //case 0xA0: // GC mode Repeat Start or Stop
<> 149:156823d33999 793 case 0x90: // GC mode Data ACK
<> 149:156823d33999 794 case 0x98: // GC mode Data NACK
<> 149:156823d33999 795 case 0x70: // GC mode Address ACK
<> 149:156823d33999 796 case 0x78: // GC mode Arbitration Lost
<> 149:156823d33999 797 obj->i2c.slaveaddr_state = WriteAddressed;
<> 149:156823d33999 798 if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
<> 149:156823d33999 799 if (obj->i2c.tran_pos < obj->i2c.tran_end) {
<> 149:156823d33999 800 if (status == 0x90 || status == 0x98) {
<> 149:156823d33999 801 *obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
<> 149:156823d33999 802 }
<> 149:156823d33999 803
<> 149:156823d33999 804 if (status == 0x98) {
<> 149:156823d33999 805 #if NU_I2C_DEBUG
<> 149:156823d33999 806 if (obj->i2c.tran_pos != obj->i2c.tran_end) {
<> 149:156823d33999 807 MY_I2C = obj->i2c;
<> 149:156823d33999 808 while (1);
<> 149:156823d33999 809 }
<> 149:156823d33999 810 #endif
<> 149:156823d33999 811 obj->i2c.slaveaddr_state = NoData;
<> 149:156823d33999 812 i2c_fsm_reset(obj, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk);
<> 149:156823d33999 813 }
<> 149:156823d33999 814 else {
<> 149:156823d33999 815 uint32_t i2c_ctl = I2C_CTL_SI_Msk | I2C_CTL_AA_Msk;
<> 149:156823d33999 816 if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
<> 149:156823d33999 817 obj->i2c.tran_ctrl & TRANCTRL_NAKLASTDATA) {
<> 149:156823d33999 818 // Last data
<> 149:156823d33999 819 i2c_ctl &= ~I2C_CTL_AA_Msk;
<> 149:156823d33999 820 }
<> 149:156823d33999 821 I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
<> 149:156823d33999 822 }
<> 149:156823d33999 823 }
<> 149:156823d33999 824 else {
<> 149:156823d33999 825 obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
<> 149:156823d33999 826 i2c_disable_int(obj);
<> 149:156823d33999 827 break;
<> 149:156823d33999 828 }
<> 149:156823d33999 829 }
<> 149:156823d33999 830 else {
<> 149:156823d33999 831 i2c_disable_int(obj);
<> 149:156823d33999 832 }
<> 149:156823d33999 833 break;
<> 149:156823d33999 834
<> 149:156823d33999 835 case 0xF8: // Bus Released
<> 149:156823d33999 836 break;
<> 149:156823d33999 837
<> 149:156823d33999 838 default:
<> 149:156823d33999 839 i2c_fsm_reset(obj, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk);
<> 149:156823d33999 840 }
<> 149:156823d33999 841 }
<> 149:156823d33999 842
<> 149:156823d33999 843 static void i2c_fsm_reset(i2c_t *obj, uint32_t i2c_ctl)
<> 149:156823d33999 844 {
<> 149:156823d33999 845 I2C_T *i2c_base = (I2C_T *) NU_MODBASE(obj->i2c.i2c);
<> 149:156823d33999 846
<> 149:156823d33999 847 obj->i2c.stop = 0;
<> 149:156823d33999 848
<> 149:156823d33999 849 obj->i2c.tran_ctrl = 0;
<> 149:156823d33999 850
<> 149:156823d33999 851 I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
<> 149:156823d33999 852 obj->i2c.slaveaddr_state = NoData;
<> 149:156823d33999 853 }
<> 149:156823d33999 854
<> 149:156823d33999 855
<> 149:156823d33999 856 #if DEVICE_I2C_ASYNCH
<> 149:156823d33999 857
<> 149:156823d33999 858 void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint32_t address, uint32_t stop, uint32_t handler, uint32_t event, DMAUsage hint)
<> 149:156823d33999 859 {
<> 149:156823d33999 860 // NOTE: NUC472 I2C only supports 7-bit slave address. The mbed I2C address passed in is shifted left by 1 bit (7-bit addr << 1).
<> 149:156823d33999 861 MBED_ASSERT((address & 0xFFFFFF00) == 0);
<> 149:156823d33999 862
<> 149:156823d33999 863 // NOTE: First transmit and then receive.
<> 149:156823d33999 864
<> 149:156823d33999 865 (void) hint;
<> 149:156823d33999 866 obj->i2c.dma_usage = DMA_USAGE_NEVER;
<> 149:156823d33999 867 obj->i2c.stop = stop;
<> 149:156823d33999 868 obj->i2c.address = address;
<> 149:156823d33999 869 obj->i2c.event = event;
<> 149:156823d33999 870 i2c_buffer_set(obj, tx, tx_length, rx, rx_length);
<> 149:156823d33999 871
<> 149:156823d33999 872 //I2C_T *i2c_base = (I2C_T *) NU_MODBASE(obj->i2c.i2c);
<> 149:156823d33999 873
<> 149:156823d33999 874 i2c_enable_vector_interrupt(obj, handler, 1);
<> 149:156823d33999 875 i2c_start(obj);
<> 149:156823d33999 876 }
<> 149:156823d33999 877
<> 149:156823d33999 878 uint32_t i2c_irq_handler_asynch(i2c_t *obj)
<> 149:156823d33999 879 {
<> 149:156823d33999 880 int event = 0;
<> 149:156823d33999 881
<> 149:156823d33999 882 I2C_T *i2c_base = (I2C_T *) NU_MODBASE(obj->i2c.i2c);
<> 149:156823d33999 883 uint32_t status = I2C_GET_STATUS(i2c_base);
<> 149:156823d33999 884 switch (status) {
<> 149:156823d33999 885 case 0x08: // Start
<> 149:156823d33999 886 case 0x10: {// Master Repeat Start
<> 149:156823d33999 887 if (obj->tx_buff.buffer && obj->tx_buff.pos < obj->tx_buff.length) {
<> 149:156823d33999 888 I2C_SET_DATA(i2c_base, (i2c_addr2data(obj->i2c.address, 0)));
<> 149:156823d33999 889 I2C_SET_CONTROL_REG(i2c_base, I2C_CTL_SI_Msk);
<> 149:156823d33999 890 }
<> 149:156823d33999 891 else if (obj->rx_buff.buffer && obj->rx_buff.pos < obj->rx_buff.length) {
<> 149:156823d33999 892 I2C_SET_DATA(i2c_base, (i2c_addr2data(obj->i2c.address, 1)));
<> 149:156823d33999 893 I2C_SET_CONTROL_REG(i2c_base, I2C_CTL_SI_Msk);
<> 149:156823d33999 894 }
<> 149:156823d33999 895 else {
<> 149:156823d33999 896 event = I2C_EVENT_TRANSFER_COMPLETE;
<> 149:156823d33999 897 if (obj->i2c.stop) {
<> 149:156823d33999 898 I2C_SET_CONTROL_REG(i2c_base, I2C_CTL_STO_Msk | I2C_CTL_SI_Msk);
<> 149:156823d33999 899 }
<> 149:156823d33999 900 }
<> 149:156823d33999 901 break;
<> 149:156823d33999 902 }
<> 149:156823d33999 903
<> 149:156823d33999 904 case 0x18: // Master Transmit Address ACK
<> 149:156823d33999 905 case 0x28: // Master Transmit Data ACK
<> 149:156823d33999 906 if (obj->tx_buff.buffer && obj->tx_buff.pos < obj->tx_buff.length) {
<> 149:156823d33999 907 uint8_t *tx = (uint8_t *)obj->tx_buff.buffer;
<> 149:156823d33999 908 I2C_SET_DATA(i2c_base, tx[obj->tx_buff.pos ++]);
<> 149:156823d33999 909 I2C_SET_CONTROL_REG(i2c_base, I2C_CTL_SI_Msk);
<> 149:156823d33999 910 }
<> 149:156823d33999 911 else if (obj->rx_buff.buffer && obj->rx_buff.pos < obj->rx_buff.length) {
<> 149:156823d33999 912 I2C_SET_CONTROL_REG(i2c_base, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk);
<> 149:156823d33999 913 }
<> 149:156823d33999 914 else {
<> 149:156823d33999 915 event = I2C_EVENT_TRANSFER_COMPLETE;
<> 149:156823d33999 916 if (obj->i2c.stop) {
<> 149:156823d33999 917 I2C_SET_CONTROL_REG(i2c_base, I2C_CTL_STO_Msk | I2C_CTL_SI_Msk);
<> 149:156823d33999 918 }
<> 149:156823d33999 919 }
<> 149:156823d33999 920 break;
<> 149:156823d33999 921
<> 149:156823d33999 922 case 0x20: // Master Transmit Address NACK
<> 149:156823d33999 923 event = I2C_EVENT_ERROR_NO_SLAVE;
<> 149:156823d33999 924 if (obj->i2c.stop) {
<> 149:156823d33999 925 I2C_SET_CONTROL_REG(i2c_base, I2C_CTL_STO_Msk | I2C_CTL_SI_Msk);
<> 149:156823d33999 926 }
<> 149:156823d33999 927 break;
<> 149:156823d33999 928
<> 149:156823d33999 929 case 0x30: // Master Transmit Data NACK
<> 149:156823d33999 930 if (obj->tx_buff.buffer && obj->tx_buff.pos < obj->tx_buff.length) {
<> 149:156823d33999 931 event = I2C_EVENT_TRANSFER_EARLY_NACK;
<> 149:156823d33999 932 I2C_SET_CONTROL_REG(i2c_base, I2C_CTL_STO_Msk | I2C_CTL_SI_Msk);
<> 149:156823d33999 933 }
<> 149:156823d33999 934 else if (obj->rx_buff.buffer && obj->rx_buff.pos < obj->rx_buff.length) {
<> 149:156823d33999 935 I2C_SET_CONTROL_REG(i2c_base, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk);
<> 149:156823d33999 936 }
<> 149:156823d33999 937 else {
<> 149:156823d33999 938 event = I2C_EVENT_TRANSFER_COMPLETE;
<> 149:156823d33999 939 if (obj->i2c.stop) {
<> 149:156823d33999 940 I2C_SET_CONTROL_REG(i2c_base, I2C_CTL_STO_Msk | I2C_CTL_SI_Msk);
<> 149:156823d33999 941 }
<> 149:156823d33999 942 }
<> 149:156823d33999 943 break;
<> 149:156823d33999 944
<> 149:156823d33999 945 case 0x38: // Master Arbitration Lost
<> 149:156823d33999 946 I2C_SET_CONTROL_REG(i2c_base, I2C_CTL_SI_Msk); // Enter not addressed SLV mode
<> 149:156823d33999 947 event = I2C_EVENT_ERROR;
<> 149:156823d33999 948 break;
<> 149:156823d33999 949
<> 149:156823d33999 950 case 0x50: // Master Receive Data ACK
<> 149:156823d33999 951 if (obj->rx_buff.buffer && obj->rx_buff.pos < obj->rx_buff.length) {
<> 149:156823d33999 952 uint8_t *rx = (uint8_t *) obj->rx_buff.buffer;
<> 149:156823d33999 953 rx[obj->rx_buff.pos ++] = I2C_GET_DATA(((I2C_T *) NU_MODBASE(obj->i2c.i2c)));
<> 149:156823d33999 954 }
<> 149:156823d33999 955 case 0x40: // Master Receive Address ACK
<> 149:156823d33999 956 I2C_SET_CONTROL_REG(i2c_base, I2C_CTL_SI_Msk | ((obj->rx_buff.pos != obj->rx_buff.length - 1) ? I2C_CTL_AA_Msk : 0));
<> 149:156823d33999 957 break;
<> 149:156823d33999 958
<> 149:156823d33999 959 case 0x48: // Master Receive Address NACK
<> 149:156823d33999 960 event = I2C_EVENT_ERROR_NO_SLAVE;
<> 149:156823d33999 961 if (obj->i2c.stop) {
<> 149:156823d33999 962 I2C_SET_CONTROL_REG(i2c_base, I2C_CTL_STO_Msk | I2C_CTL_SI_Msk);
<> 149:156823d33999 963 }
<> 149:156823d33999 964 break;
<> 149:156823d33999 965
<> 149:156823d33999 966 case 0x58: // Master Receive Data NACK
<> 149:156823d33999 967 if (obj->rx_buff.buffer && obj->rx_buff.pos < obj->rx_buff.length) {
<> 149:156823d33999 968 uint8_t *rx = (uint8_t *) obj->rx_buff.buffer;
<> 149:156823d33999 969 rx[obj->rx_buff.pos ++] = I2C_GET_DATA(((I2C_T *) NU_MODBASE(obj->i2c.i2c)));
<> 149:156823d33999 970 }
<> 149:156823d33999 971 I2C_SET_CONTROL_REG(i2c_base, I2C_CTL_STA_Msk | I2C_CTL_SI_Msk);
<> 149:156823d33999 972 break;
<> 149:156823d33999 973
<> 149:156823d33999 974 case 0x00: // Bus error
<> 149:156823d33999 975 event = I2C_EVENT_ERROR;
<> 149:156823d33999 976 i2c_reset(obj);
<> 149:156823d33999 977 break;
<> 149:156823d33999 978
<> 149:156823d33999 979 default:
<> 149:156823d33999 980 event = I2C_EVENT_ERROR;
<> 149:156823d33999 981 if (obj->i2c.stop) {
<> 149:156823d33999 982 I2C_SET_CONTROL_REG(i2c_base, I2C_CTL_STO_Msk | I2C_CTL_SI_Msk);
<> 149:156823d33999 983 }
<> 149:156823d33999 984 }
<> 149:156823d33999 985
<> 149:156823d33999 986 if (event) {
<> 149:156823d33999 987 i2c_rollback_vector_interrupt(obj);
<> 149:156823d33999 988 }
<> 149:156823d33999 989
<> 149:156823d33999 990 return (event & obj->i2c.event);
<> 149:156823d33999 991 }
<> 149:156823d33999 992
<> 149:156823d33999 993 uint8_t i2c_active(i2c_t *obj)
<> 149:156823d33999 994 {
<> 149:156823d33999 995 const struct nu_modinit_s *modinit = get_modinit(obj->i2c.i2c, i2c_modinit_tab);
<> 149:156823d33999 996 MBED_ASSERT(modinit != NULL);
<> 149:156823d33999 997 MBED_ASSERT(modinit->modname == obj->i2c.i2c);
<> 149:156823d33999 998
<> 149:156823d33999 999 // Vector will be changed for async transfer. Use it to judge if async transfer is on-going.
<> 149:156823d33999 1000 uint32_t vec = NVIC_GetVector(modinit->irq_n);
<> 149:156823d33999 1001 struct nu_i2c_var *var = (struct nu_i2c_var *) modinit->var;
<> 149:156823d33999 1002 return (vec && vec != (uint32_t) var->vec);
<> 149:156823d33999 1003 }
<> 149:156823d33999 1004
<> 149:156823d33999 1005 void i2c_abort_asynch(i2c_t *obj)
<> 149:156823d33999 1006 {
<> 149:156823d33999 1007 i2c_rollback_vector_interrupt(obj);
<> 149:156823d33999 1008 i2c_stop(obj);
<> 149:156823d33999 1009 }
<> 149:156823d33999 1010
<> 149:156823d33999 1011 static void i2c_buffer_set(i2c_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length)
<> 149:156823d33999 1012 {
<> 149:156823d33999 1013 obj->tx_buff.buffer = (void *) tx;
<> 149:156823d33999 1014 obj->tx_buff.length = tx_length;
<> 149:156823d33999 1015 obj->tx_buff.pos = 0;
<> 149:156823d33999 1016 obj->rx_buff.buffer = rx;
<> 149:156823d33999 1017 obj->rx_buff.length = rx_length;
<> 149:156823d33999 1018 obj->rx_buff.pos = 0;
<> 149:156823d33999 1019 }
<> 149:156823d33999 1020
<> 149:156823d33999 1021 static void i2c_enable_vector_interrupt(i2c_t *obj, uint32_t handler, int enable)
<> 149:156823d33999 1022 {
<> 149:156823d33999 1023 const struct nu_modinit_s *modinit = get_modinit(obj->i2c.i2c, i2c_modinit_tab);
<> 149:156823d33999 1024 MBED_ASSERT(modinit != NULL);
<> 149:156823d33999 1025 MBED_ASSERT(modinit->modname == obj->i2c.i2c);
<> 149:156823d33999 1026
<> 149:156823d33999 1027 if (enable) {
<> 149:156823d33999 1028 NVIC_SetVector(modinit->irq_n, handler);
<> 149:156823d33999 1029 i2c_enable_int(obj);
<> 149:156823d33999 1030 }
<> 149:156823d33999 1031 else {
<> 149:156823d33999 1032 i2c_disable_int(obj);
<> 149:156823d33999 1033 }
<> 149:156823d33999 1034 }
<> 149:156823d33999 1035
<> 149:156823d33999 1036 static void i2c_rollback_vector_interrupt(i2c_t *obj)
<> 149:156823d33999 1037 {
<> 149:156823d33999 1038 const struct nu_modinit_s *modinit = get_modinit(obj->i2c.i2c, i2c_modinit_tab);
<> 149:156823d33999 1039 MBED_ASSERT(modinit != NULL);
<> 149:156823d33999 1040 MBED_ASSERT(modinit->modname == obj->i2c.i2c);
<> 149:156823d33999 1041
<> 149:156823d33999 1042 struct nu_i2c_var *var = (struct nu_i2c_var *) modinit->var;
<> 149:156823d33999 1043 i2c_enable_vector_interrupt(obj, (uint32_t) var->vec, 1);
<> 149:156823d33999 1044 }
<> 149:156823d33999 1045
<> 149:156823d33999 1046 #endif
<> 149:156823d33999 1047
<> 149:156823d33999 1048 #endif