added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
<>
Date:
Fri Sep 02 15:07:44 2016 +0100
Revision:
144:ef7eb2e8f9f7
This updates the lib to the mbed lib v125

Who changed what in which revision?

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