1 /* ****************************************************************************
2 * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Except as contained in this notice, the name of Maxim Integrated
23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
24 * Products, Inc. Branding Policy.
25 *
26 * The mere transfer of this software does not imply any licenses
27 * of trade secrets, proprietary technology, copyrights, patents,
28 * trademarks, maskwork rights, or any other form of intellectual
29 * property whatsoever. Maxim Integrated Products, Inc. retains all
30 * ownership rights.
31 *
32 * $Date: 2020-02-03 10:33:50 -0600 (Mon, 03 Feb 2020) $
33 * $Revision: 51326 $
34 *
35 *************************************************************************** */
36
37
38 #include <stddef.h>
39 #include <stdint.h>
40 #include "mxc_config.h"
41 #include "mxc_assert.h"
42 #include "mxc_lock.h"
43 #include "mxc_sys.h"
44 #include "i2c.h"
45 #include <stdio.h>
46 #include "mxc_delay.h"
47
48 /* **** Definitions **** */
49 #define I2C_ERROR (MXC_F_I2C_INT_FL0_ARB_ER | MXC_F_I2C_INT_FL0_TO_ER | MXC_F_I2C_INT_FL0_ADDR_NACK_ER | \
50 MXC_F_I2C_INT_FL0_DATA_ER | MXC_F_I2C_INT_FL0_DO_NOT_RESP_ER | MXC_F_I2C_INT_FL0_START_ER | \
51 MXC_F_I2C_INT_FL0_STOP_ER)
52 #define MASTER 1
53 #define SLAVE 0
54
55 /* For high speed mode, if the I2C bus capacitance is greater than 100pF, set this value to ((capacitance - 100) / 3).
56 Otherwise leave it at 0. */
57 #define HS_SCALE_FACTOR (0)
58
59 #define T_LOW_MIN (160 + (160 * HS_SCALE_FACTOR / 100)) /* tLOW minimum in nanoseconds */
60 #define T_HIGH_MIN (60 + (60 * HS_SCALE_FACTOR / 100)) /* tHIGH minimum in nanoseconds */
61 #define T_R_MAX_HS (40 + (40 * HS_SCALE_FACTOR / 100)) /* tR maximum for high speed mode in nanoseconds */
62 #define T_F_MAX_HS (40 + (40 * HS_SCALE_FACTOR / 100)) /* tF maximum for high speed mode in nanoseconds */
63 #define T_AF_MIN (10 + (10 * HS_SCALE_FACTOR / 100)) /* tAF minimun in nanoseconds */
64
65 /* **** Variable Declaration **** */
66
67 // Saves the state of the non-blocking requests
68 typedef struct {
69 i2c_req_t *req;
70 i2c_state_t state;
71 uint8_t num_wr; // keep track of number of bytes loaded in the fifo during slave transmit
72 } i2c_req_state_t;
73 static i2c_req_state_t states[MXC_I2C_INSTANCES];
74
75 /* **** Function Prototypes **** */
76 static void I2C_MasterHandler(mxc_i2c_regs_t *i2c);
77 static void I2C_SlaveHandler(mxc_i2c_regs_t *i2c);
78 static void I2C_FreeCallback(int i2c_num, int error);
79 static void I2C_Recover(mxc_i2c_regs_t *i2c);
80
81 /* ************************************************************************** */
I2C_Setspeed(mxc_i2c_regs_t * i2c,i2c_speed_t i2cspeed)82 static int I2C_Setspeed(mxc_i2c_regs_t * i2c, i2c_speed_t i2cspeed)
83 {
84 uint32_t ticks, ticks_lo, ticks_hi;
85
86 if (i2cspeed == I2C_HS_MODE) {
87
88 uint32_t sys_freq, tPCLK, targBusFreq, tSCLmin, cklMin, ckhMin, ckh_cklMin;
89
90 /* Compute dividers for high speed mode. */
91 sys_freq = SYS_I2C_GetFreq(i2c);
92 MXC_ASSERT(sys_freq >= 1000);
93
94 tPCLK = 1000000 / (sys_freq / 1000);
95 MXC_ASSERT(tPCLK > 0)
96
97 targBusFreq = i2cspeed - ((i2cspeed/2) * HS_SCALE_FACTOR / 100);
98 if(targBusFreq < 1000) {
99 return E_BAD_PARAM;
100 }
101
102 tSCLmin = 1000000 / (targBusFreq / 1000);
103 cklMin = ((T_LOW_MIN + T_F_MAX_HS + (tPCLK - 1) - T_AF_MIN) / tPCLK) - 1;
104 ckhMin = ((T_HIGH_MIN + T_R_MAX_HS + (tPCLK - 1) - T_AF_MIN) / tPCLK) - 1;
105 ckh_cklMin = ((tSCLmin + (tPCLK - 1)) / tPCLK) - 2;
106
107 ticks_lo = (cklMin > (ckh_cklMin - ckhMin)) ? (cklMin) : (ckh_cklMin - ckhMin);
108 ticks_hi = ckhMin;
109
110 if((ticks_lo > (MXC_F_I2C_HS_CLK_HS_CLK_LO >> MXC_F_I2C_HS_CLK_HS_CLK_LO_POS)) ||
111 (ticks_hi > (MXC_F_I2C_HS_CLK_HS_CLK_HI >> MXC_F_I2C_HS_CLK_HS_CLK_HI_POS))) {
112 return E_BAD_PARAM;
113 }
114
115 /* Write results to destination registers. */
116 i2c->hs_clk = (ticks_lo << MXC_F_I2C_HS_CLK_HS_CLK_LO_POS) | (ticks_hi <<
117 MXC_F_I2C_HS_CLK_HS_CLK_HI_POS);
118
119 /* Still need to load dividers for the preamble that each high-speed transaction starts with.
120 Switch setting to fast mode and fall out of if statement. */
121 i2cspeed = I2C_FAST_MODE;
122 }
123
124 /* Get the number of periph clocks needed to achieve selected speed. */
125 ticks = SYS_I2C_GetFreq(i2c) / i2cspeed;
126
127 /* For a 50% duty cycle, half the ticks will be spent high and half will be low. */
128 ticks_hi = (ticks >> 1) - 1;
129 ticks_lo = (ticks >> 1) - 1;
130
131 /* Account for rounding error in odd tick counts. */
132 if (ticks & 1) {
133 ticks_hi++;
134 }
135
136 /* Will results fit into 9 bit registers? (ticks_hi will always be >= ticks_lo. No need to check ticks_lo.) */
137 if (ticks_hi > 0x1FF) {
138 return E_BAD_PARAM;
139 }
140
141 /* 0 is an invalid value for the destination registers. (ticks_hi will always be >= ticks_lo. No need to check ticks_hi.) */
142 if (ticks_lo == 0) {
143 return E_BAD_PARAM;
144 }
145
146 /* Write results to destination registers. */
147 i2c->clk_lo = ticks_lo;
148 i2c->clk_hi = ticks_hi;
149
150 return E_NO_ERROR;
151 }
152
153 /* ************************************************************************** */
I2C_Init(mxc_i2c_regs_t * i2c,i2c_speed_t i2cspeed,const sys_cfg_i2c_t * sys_cfg)154 int I2C_Init(mxc_i2c_regs_t *i2c, i2c_speed_t i2cspeed, const sys_cfg_i2c_t* sys_cfg)
155 {
156 int err;
157 int idx = MXC_I2C_GET_IDX(i2c);
158 // Check the base pointer
159 MXC_ASSERT(idx >= 0);
160
161 // Set system level configurations
162 if ((err = SYS_I2C_Init(i2c, sys_cfg)) != E_NO_ERROR) {
163 return err;
164 }
165
166 // Always disable the HW autoflush on data NACK and let the SW handle the flushing.
167 i2c->tx_ctrl0 |= 0x20;
168
169 states[idx].num_wr = 0;
170
171 i2c->ctrl = 0; // clear configuration bits
172 i2c->ctrl = MXC_F_I2C_CTRL_I2C_EN; // Enable I2C
173 i2c->master_ctrl = 0; // clear master configuration bits
174 i2c->status = 0; // clear status bits
175
176 /* If either SDA or SCL is already low, there is a problem.
177 * Try reclaiming the bus by sending clocks until we have control of the SDA line.
178 * Follow procedure defined in i2c spec.
179 */
180 if ((i2c->ctrl & (MXC_F_I2C_CTRL_SCL | MXC_F_I2C_CTRL_SDA)) !=
181 (MXC_F_I2C_CTRL_SCL | MXC_F_I2C_CTRL_SDA)) {
182
183 int i, have_control;
184
185 // Set SCL/SDA as software controlled.
186 i2c->ctrl |= MXC_F_I2C_CTRL_SW_OUT_EN;
187
188 // Try to get control of SDA.
189 for (i = 0; i < 16; i++) {
190 have_control = 1;
191
192 // Drive SCL low and check its state.
193 i2c->ctrl &= ~(MXC_F_I2C_CTRL_SCL_OUT);
194 mxc_delay(MXC_DELAY_USEC(5));
195 if ((i2c->ctrl & MXC_F_I2C_CTRL_SCL) == MXC_F_I2C_CTRL_SCL) {
196 have_control = 0;
197 }
198
199 // Drive SDA low and check its state.
200 i2c->ctrl &= ~(MXC_F_I2C_CTRL_SDA_OUT);
201 mxc_delay(MXC_DELAY_USEC(5));
202 if ((i2c->ctrl & MXC_F_I2C_CTRL_SDA) == MXC_F_I2C_CTRL_SDA) {
203 have_control = 0;
204 }
205
206 // Release SDA and check its state.
207 i2c->ctrl |= (MXC_F_I2C_CTRL_SDA_OUT);
208 mxc_delay(MXC_DELAY_USEC(5));
209 if ((i2c->ctrl & MXC_F_I2C_CTRL_SDA) != MXC_F_I2C_CTRL_SDA) {
210 have_control = 0;
211 }
212
213 // Release SCL and check its state.
214 i2c->ctrl |= (MXC_F_I2C_CTRL_SCL_OUT);
215 mxc_delay(MXC_DELAY_USEC(5));
216 if ((i2c->ctrl & MXC_F_I2C_CTRL_SCL) != MXC_F_I2C_CTRL_SCL) {
217 have_control = 0;
218 }
219
220 if (have_control) {
221 // Issue stop
222 // Drive SDA low.
223 i2c->ctrl &= ~(MXC_F_I2C_CTRL_SDA_OUT);
224 mxc_delay(MXC_DELAY_USEC(5));
225 // Release SDA.
226 i2c->ctrl |= (MXC_F_I2C_CTRL_SDA_OUT);
227 mxc_delay(MXC_DELAY_USEC(5));
228 break;
229 }
230 }
231
232 if (!have_control) {
233 return E_COMM_ERR;
234 }
235 }
236
237 i2c->ctrl = 0; // clear configuration bits
238 i2c->ctrl = MXC_F_I2C_CTRL_I2C_EN; // Enable I2C
239 i2c->master_ctrl = 0; // clear master configuration bits
240 i2c->status= 0; // clear status bits
241
242 // Check for HS mode
243 if (i2cspeed == I2C_HS_MODE) {
244 i2c->ctrl |= MXC_F_I2C_CTRL_HS_MODE; // Enable HS mode
245 }
246
247 // Disable and clear interrupts
248 i2c->int_en0 = 0;
249 i2c->int_en1 = 0;
250 i2c->int_fl0 = i2c->int_fl0;
251 i2c->int_fl1 = i2c->int_fl1;
252
253 i2c->timeout = 0x0; // set timeout
254 i2c->rx_ctrl0 |= MXC_F_I2C_RX_CTRL0_RX_FLUSH; // clear the RX FIFO
255 i2c->tx_ctrl0 |= MXC_F_I2C_TX_CTRL0_TX_FLUSH; // clear the TX FIFO
256
257 return I2C_Setspeed(i2c, i2cspeed);
258 }
259 /* ************************************************************************** */
I2C_Shutdown(mxc_i2c_regs_t * i2c)260 int I2C_Shutdown(mxc_i2c_regs_t *i2c)
261 {
262 int i2c_num, err;
263
264 // Check the base pointer
265 i2c_num = MXC_I2C_GET_IDX(i2c);
266 MXC_ASSERT(i2c_num >= 0);
267
268 // Disable and clear interrupts
269 i2c->int_en0 = 0;
270 i2c->int_en1 = 0;
271 i2c->int_fl0 = i2c->int_fl0;
272 i2c->int_fl1 = i2c->int_fl1;
273
274 i2c->rx_ctrl0 |= MXC_F_I2C_RX_CTRL0_RX_FLUSH; // clear the RX FIFO
275 i2c->tx_ctrl0 |= MXC_F_I2C_TX_CTRL0_TX_FLUSH; // clear the TX FIFO
276
277 // Call all of the pending callbacks for this I2C
278 if (states[i2c_num].req != NULL) {
279 I2C_Recover(i2c);
280 I2C_FreeCallback(i2c_num, E_SHUTDOWN);
281 }
282
283 i2c->ctrl = 0;
284
285 // Clears system level configurations
286 if ((err = SYS_I2C_Shutdown(i2c)) != E_NO_ERROR) {
287 return err;
288 }
289
290 return E_NO_ERROR;
291 }
292
293 /* ************************************************************************** */
I2C_MasterWrite(mxc_i2c_regs_t * i2c,uint8_t addr,const uint8_t * data,int len,int restart)294 int I2C_MasterWrite(mxc_i2c_regs_t *i2c, uint8_t addr, const uint8_t* data, int len, int restart)
295 {
296 int save_len = len;
297
298 if (len == 0) {
299 return E_NO_ERROR;
300 }
301
302 // Clear the lock out bit (W1C) in case it is set.
303 i2c->int_fl0 = MXC_F_I2C_INT_FL0_TX_LOCK_OUT;
304 i2c->int_fl0 = i2c->int_fl0;
305
306 // Enable master mode
307 i2c->ctrl |= MXC_F_I2C_CTRL_MST;
308
309 // Load FIFO with slave address for WRITE and as much data as we can
310 while (i2c->status & MXC_F_I2C_STATUS_TX_FULL) {}
311 i2c->fifo = addr & ~(0x1);
312
313 while ((len > 0) && !(i2c->status & MXC_F_I2C_STATUS_TX_FULL)) {
314 i2c->fifo = *data++;
315 len--;
316 }
317
318 i2c->master_ctrl |= MXC_F_I2C_MASTER_CTRL_START;
319
320 // Write remaining data to FIFO
321 while (len > 0) {
322
323 // Check for errors
324 if (i2c->int_fl0 & I2C_ERROR) {
325 // Set the stop bit
326 i2c->master_ctrl &= ~(MXC_F_I2C_MASTER_CTRL_RESTART);
327 i2c->master_ctrl |= MXC_F_I2C_MASTER_CTRL_STOP;
328 while (!(i2c->int_fl0 & (MXC_F_I2C_INT_FL0_STOP))) {}
329
330 return E_COMM_ERR;
331 }
332
333 if (!(i2c->status & MXC_F_I2C_STATUS_TX_FULL)) {
334 i2c->fifo = *data++;
335 len--;
336 }
337 }
338
339 if (restart) {
340 i2c->master_ctrl |= MXC_F_I2C_MASTER_CTRL_RESTART;
341 } else {
342 i2c->master_ctrl |= MXC_F_I2C_MASTER_CTRL_STOP;
343 }
344
345 // Wait for Done or time out if enabled
346 while (!(i2c->int_fl0 & (MXC_F_I2C_INT_FL0_DONE | I2C_ERROR ))) {}
347
348 i2c->int_fl0 = MXC_F_I2C_INT_FL0_DONE;
349
350 // Wait for Stop
351 if (!restart) {
352 while (!(i2c->int_fl0 & (MXC_F_I2C_INT_FL0_STOP ))) {}
353
354 i2c->int_fl0 = MXC_F_I2C_INT_FL0_STOP;
355 }
356
357 // Check for errors
358 if (i2c->int_fl0 & I2C_ERROR) {
359 return E_COMM_ERR;
360 }
361
362 return save_len;
363 }
364
365 /* ************************************************************************** */
I2C_MasterRead(mxc_i2c_regs_t * i2c,uint8_t addr,uint8_t * data,int len,int restart)366 int I2C_MasterRead(mxc_i2c_regs_t *i2c, uint8_t addr, uint8_t* data, int len, int restart)
367 {
368 int save_len = len;
369
370 if (len == 0) {
371 return E_NO_ERROR;
372 }
373
374 if (len > 256) {
375 return E_BAD_PARAM;
376 }
377
378 i2c->int_fl0 = MXC_F_I2C_INT_FL0_TX_LOCK_OUT;
379 i2c->int_fl0 = i2c->int_fl0;
380
381 // Make sure the I2C has been initialized
382 if (!(i2c->ctrl & MXC_F_I2C_CTRL_I2C_EN)) {
383 return E_UNINITIALIZED;
384 }
385
386 // Enable master mode
387 i2c->ctrl |= MXC_F_I2C_CTRL_MST;
388
389 // Set receive count
390 i2c->rx_ctrl1= len;
391
392 i2c->master_ctrl |= MXC_F_I2C_MASTER_CTRL_START;
393
394 // Load FIFO with slave address
395 while (i2c->status & MXC_F_I2C_STATUS_TX_FULL) {}
396 i2c->fifo = (addr | 1);
397
398
399 // Wait for all data to be received or error
400 while (len > 0) {
401
402 // Check for errors
403 if (i2c->int_fl0 & I2C_ERROR) {
404 // Set the stop bit
405 i2c->master_ctrl |= MXC_F_I2C_MASTER_CTRL_STOP;
406 return E_COMM_ERR;
407 }
408
409 if (!(i2c->status & MXC_F_I2C_STATUS_RX_EMPTY)) {
410 *data++ = i2c->fifo;
411 len--;
412 }
413 }
414
415 if (i2c->int_fl0 & I2C_ERROR) {
416 // Set the stop bit
417 i2c->master_ctrl |= MXC_F_I2C_MASTER_CTRL_STOP;
418 return E_COMM_ERR;
419 }
420
421 if (restart) {
422 i2c->master_ctrl |= MXC_F_I2C_MASTER_CTRL_RESTART;
423 } else {
424 i2c->master_ctrl |= MXC_F_I2C_MASTER_CTRL_STOP;
425 }
426
427 // Wait for Done or time out if enabled
428 while (!(i2c->int_fl0 & (MXC_F_I2C_INT_FL0_DONE | I2C_ERROR ))) {}
429
430 i2c->int_fl0 = MXC_F_I2C_INT_FL0_DONE;
431
432 // Wait for Stop
433 if (!restart) {
434 while (!(i2c->int_fl0 & (MXC_F_I2C_INT_FL0_STOP | I2C_ERROR))) {
435
436 }
437
438 i2c->int_fl0 = MXC_F_I2C_INT_FL0_STOP;
439 }
440
441 // Check for errors
442 if (i2c->int_fl0 & I2C_ERROR) {
443 return E_COMM_ERR;
444 }
445
446 return save_len;
447 }
448
449 /* ************************************************************************** */
I2C_Slave(mxc_i2c_regs_t * i2c,uint8_t addr,const uint8_t * read_data,int read_len,uint8_t * write_data,int write_len,int * tx_num,int * rx_num,i2c_autoflush_disable_t sw_autoflush_disable)450 int I2C_Slave(mxc_i2c_regs_t *i2c, uint8_t addr, const uint8_t* read_data, int read_len,
451 uint8_t* write_data, int write_len, int* tx_num, int* rx_num,
452 i2c_autoflush_disable_t sw_autoflush_disable)
453 {
454 int i2c_num;
455
456 i2c_num = MXC_I2C_GET_IDX(i2c);
457 if ((read_data == NULL) && (write_data == NULL)) {
458 return E_NULL_PTR;
459 }
460
461 // Make sure the I2C has been initialized
462 if (!(i2c->ctrl & MXC_F_I2C_CTRL_I2C_EN)) {
463 return E_UNINITIALIZED;
464 }
465
466 if ((read_len == 0) && (write_len == 0)) {
467 return E_NO_ERROR;
468 }
469
470 if (mxc_get_lock((uint32_t*)&states[i2c_num].req, 1) != E_NO_ERROR) {
471 return E_BUSY;
472 }
473 // Disable master mode
474 i2c->ctrl &= ~MXC_F_I2C_CTRL_MST;
475
476 // Clear any previous errors
477 i2c->int_fl0 = i2c->int_fl0;
478 i2c->int_fl1 = i2c->int_fl1;
479
480 // Set the slave address
481 i2c->slave_addr = (addr >> 1);
482
483 // Wait for address match
484 while (!(i2c->int_fl0 & MXC_F_I2C_INT_FL0_ADDR_MATCH) && !(i2c->int_fl0 & I2C_ERROR)) {
485
486 }
487
488 i2c->int_fl0 = MXC_F_I2C_INT_FL0_ADDR_MATCH;
489 i2c->int_fl0 = MXC_F_I2C_INT_FL0_TX_LOCK_OUT;
490
491 if (i2c->int_fl0 & I2C_ERROR) {
492 if (!sw_autoflush_disable) {
493 i2c->tx_ctrl0 |= MXC_F_I2C_TX_CTRL0_TX_FLUSH;
494 i2c->rx_ctrl0 |= MXC_F_I2C_RX_CTRL0_RX_FLUSH;
495 }
496 mxc_free_lock((uint32_t*)&states[i2c_num]);
497 return E_COMM_ERR;
498 }
499
500 // See if we're reading or writing
501 if (i2c->ctrl & MXC_F_I2C_CTRL_READ) {
502 // This is the master read/slave write case
503 if (read_data == NULL || read_len == 0) {
504 mxc_free_lock((uint32_t*)&states[i2c_num]);
505 return E_NULL_PTR;
506 }
507
508 // Wait for all data to be received or error
509 while (read_len > 0) {
510
511 // Check for errors
512 if (i2c->int_fl0 & I2C_ERROR) {
513 *tx_num = states[i2c_num].num_wr - ((i2c->tx_ctrl1 & MXC_F_I2C_TX_CTRL1_TX_FIFO) >> MXC_F_I2C_TX_CTRL1_TX_FIFO_POS);
514 states[i2c_num].num_wr = 0;
515 if (!sw_autoflush_disable) {
516 i2c->tx_ctrl0 |= MXC_F_I2C_TX_CTRL0_TX_FLUSH;
517 }
518 mxc_free_lock((uint32_t*)&states[i2c_num]);
519 return E_COMM_ERR;
520 }
521
522 // Check for nack from master
523 if (i2c->int_fl0 & MXC_F_I2C_INT_FL0_TX_LOCK_OUT) {
524 break;
525 }
526
527 // Check for done bit
528 if (i2c->int_fl0 & MXC_F_I2C_INT_FL0_DONE) {
529 break;
530 }
531
532 if (!(i2c->status & MXC_F_I2C_STATUS_TX_FULL)) {
533 i2c->fifo = *read_data++;
534 states[i2c_num].num_wr++;
535 read_len--;
536 }
537 }
538
539 // Wait for Done
540 while (!(i2c->int_fl0 & MXC_F_I2C_INT_FL0_DONE)) {}
541
542 // Calculate number of bytes sent by the slave
543 *tx_num = states[i2c_num].num_wr - ((i2c->tx_ctrl1 & MXC_F_I2C_TX_CTRL1_TX_FIFO) >> MXC_F_I2C_TX_CTRL1_TX_FIFO_POS);
544 states[i2c_num].num_wr = 0;
545 if (!sw_autoflush_disable) {
546 // Flush the TX FIFO
547 i2c->tx_ctrl0 |= MXC_F_I2C_TX_CTRL0_TX_FLUSH;
548 }
549
550 } else {
551 // This is the master write/slave read case
552 if (write_data == NULL || write_len == 0) {
553 mxc_free_lock((uint32_t*)&states[i2c_num]);
554 return E_NULL_PTR;
555 }
556
557 // Wait for all data to be written or error
558 while (write_len > 0) {
559
560 // Check for errors
561 if (i2c->int_fl0 & I2C_ERROR) {
562 if (!sw_autoflush_disable) {
563 i2c->rx_ctrl0 |= MXC_F_I2C_RX_CTRL0_RX_FLUSH;
564 }
565 mxc_free_lock((uint32_t*)&states[i2c_num]);
566 return E_COMM_ERR;
567 }
568
569 // Check for done bit
570 if (i2c->int_fl0 & MXC_F_I2C_INT_FL0_DONE) {
571 break;
572 }
573
574 if (!(i2c->status & MXC_F_I2C_STATUS_RX_EMPTY)) {
575 *write_data++ = i2c->fifo;
576 (*rx_num)++;
577 write_len--;
578 }
579 }
580
581 // Wait for Done
582 while (!(i2c->int_fl0 & MXC_F_I2C_INT_FL0_DONE)) {
583
584 }
585 // Flush the FIFO
586 if (!sw_autoflush_disable) {
587 i2c->rx_ctrl0 |= MXC_F_I2C_RX_CTRL0_RX_FLUSH;
588 }
589 }
590
591 // Check for errors
592 if (i2c->int_fl0 & I2C_ERROR) {
593 // Flush the FIFO
594 if (!sw_autoflush_disable) {
595 i2c->tx_ctrl0 |= MXC_F_I2C_TX_CTRL0_TX_FLUSH;
596 i2c->rx_ctrl0 |= MXC_F_I2C_RX_CTRL0_RX_FLUSH;
597 }
598 mxc_free_lock((uint32_t*)&states[i2c_num]);
599 return E_COMM_ERR;
600 }
601 mxc_free_lock((uint32_t*)&states[i2c_num]);
602 return E_NO_ERROR;
603 }
604
605 /* ************************************************************************** */
I2C_MasterAsync(mxc_i2c_regs_t * i2c,i2c_req_t * req)606 int I2C_MasterAsync(mxc_i2c_regs_t *i2c, i2c_req_t *req)
607 {
608 int i2c_num;
609
610 i2c_num = MXC_I2C_GET_IDX(i2c);
611 if (req->state == I2C_STATE_READING) {
612 // Check the parameters
613 if (req->rx_len == 0) {
614 return E_NO_ERROR;
615 }
616 if (req->rx_data == NULL) {
617 return E_NULL_PTR;
618 }
619
620 } else {
621 // Check the parameters
622 if (req->tx_len == 0) {
623 return E_NO_ERROR;
624 }
625 if (req->tx_data == NULL) {
626 return E_NULL_PTR;
627 }
628 }
629
630 // Make sure the I2C has been initialized
631 if (!(i2c->ctrl & MXC_F_I2C_CTRL_I2C_EN)) {
632 return E_UNINITIALIZED;
633 }
634
635 // Attempt to register this request
636 if (mxc_get_lock((uint32_t*)&states[i2c_num].req, (uint32_t)req) != E_NO_ERROR) {
637 return E_BUSY;
638 }
639 states[i2c_num].state = req->state;
640 states[i2c_num].req = req;
641
642 // Enable master mode
643 i2c->ctrl |= MXC_F_I2C_CTRL_MST;
644
645 // Clear the byte counters
646 req->tx_num = 0;
647 req->rx_num = 0;
648
649 // Disable and clear the interrupts
650 i2c->int_en0 = 0;
651 i2c->int_en1 = 0;
652 i2c->int_fl0 = i2c->int_fl0;
653 i2c->int_fl1 = i2c->int_fl1;
654
655 // Start the transaction
656 I2C_MasterHandler(i2c);
657 return E_NO_ERROR;
658 }
659
660
661 /* ************************************************************************** */
I2C_MasterHandler(mxc_i2c_regs_t * i2c)662 static void I2C_MasterHandler(mxc_i2c_regs_t *i2c)
663 {
664
665 uint32_t int0, inten0 = 0;
666 int rx_remain, tx_remain, i2c_num;
667 i2c_req_t *req;
668
669 i2c_num = MXC_I2C_GET_IDX(i2c);
670 req = states[i2c_num].req;
671
672 // Check for errors
673 int0 = i2c->int_fl0;
674 if (int0 & I2C_ERROR) {
675
676 // Set the done bit
677 i2c->master_ctrl &= ~(MXC_F_I2C_MASTER_CTRL_RESTART);
678 i2c->master_ctrl |= MXC_F_I2C_MASTER_CTRL_STOP;
679
680 i2c->int_en0 = 0;
681 if (req->callback != NULL) {
682 I2C_Recover(i2c);
683 I2C_FreeCallback(i2c_num, E_COMM_ERR);
684 }
685 return;
686 }
687
688 rx_remain = req->rx_len - req->rx_num;
689 tx_remain = req->tx_len - req->tx_num;
690 if (req->restart) {
691 // Check for DONE interrupt
692 if ((int0 & MXC_F_I2C_INT_FL0_DONE)) {
693 // Read out any data in the RX FIFO
694 while (rx_remain && !(i2c->status & MXC_F_I2C_STATUS_RX_EMPTY)) {
695 *(req->rx_data)++ = i2c->fifo;
696 req->rx_num++;
697 rx_remain--;
698 }
699 i2c->int_en0 = 0;
700 if (req->callback != NULL) {
701 I2C_Recover(i2c);
702 I2C_FreeCallback(i2c_num, E_NO_ERROR);
703 }
704 return;
705 }
706 } else {
707 // Check for STOP interrupt
708 if ((int0 & MXC_F_I2C_INT_FL0_STOP)) {
709 i2c->int_en0 = 0;
710 if (req->callback != NULL) {
711 I2C_Recover(i2c);
712 I2C_FreeCallback(i2c_num, E_NO_ERROR);
713 }
714
715 return;
716 }
717
718 // Check for DONE interrupt
719 if ((int0 & MXC_F_I2C_INT_FL0_DONE)) {
720 // Read out any data in the RX FIFO
721 while (rx_remain && !(i2c->status & MXC_F_I2C_STATUS_RX_EMPTY)) {
722 *(req->rx_data)++ = i2c->fifo;
723 req->rx_num++;
724 rx_remain--;
725 }
726
727 return;
728 }
729 }
730
731 // Clear the interrupts
732 i2c->int_fl0 = int0;
733
734 if (states[i2c_num].state == I2C_STATE_READING) {
735
736
737 // Read out any data in the RX FIFO
738 while (rx_remain && !(i2c->status & MXC_F_I2C_STATUS_RX_EMPTY)) {
739 *(req->rx_data)++ = i2c->fifo;
740 req->rx_num++;
741 rx_remain--;
742 }
743
744 // Load the slave address if we haven't already started reading the data
745 if (rx_remain == req->rx_len) {
746 i2c->fifo = (req->addr | 1);
747
748 // Set the RX Count
749 i2c->rx_ctrl1 = req->rx_len;
750
751 // Start transmission if idle
752 if (!(i2c->status & MXC_F_I2C_STATUS_BUS)) {
753 i2c->master_ctrl |= MXC_F_I2C_MASTER_CTRL_START;
754 }
755
756 // Set restart or stop
757 if (req->restart) {
758 i2c->master_ctrl |= MXC_F_I2C_MASTER_CTRL_RESTART;
759 } else {
760 i2c->master_ctrl |= MXC_F_I2C_MASTER_CTRL_STOP;
761 inten0 |= MXC_F_I2C_INT_EN0_STOP;
762 }
763 }
764
765 // Set the RX threshold interrupt level
766 if (rx_remain >= (MXC_I2C_FIFO_DEPTH - 1)) {
767 i2c->rx_ctrl1 = ((i2c->rx_ctrl1 & ~(MXC_F_I2C_RX_CTRL0_RX_THRESH)) |
768 (MXC_I2C_FIFO_DEPTH - 1) << MXC_F_I2C_RX_CTRL0_RX_THRESH_POS);
769
770 inten0 |= MXC_F_I2C_INT_EN0_RX_THRESH;
771 }else{
772 i2c->rx_ctrl1 = ((i2c->rx_ctrl1 & ~(MXC_F_I2C_RX_CTRL0_RX_THRESH)) |
773 (rx_remain) << MXC_F_I2C_RX_CTRL0_RX_THRESH_POS);
774
775 inten0 |= MXC_F_I2C_INT_EN0_RX_THRESH;
776 }
777
778 } else {
779
780 // Load the slave address if we haven't already started writing the data
781 if (tx_remain == req->tx_len) {
782 i2c->fifo = req->addr;
783 // Start transmission if idle
784 if (!(i2c->status & MXC_F_I2C_STATUS_BUS)) {
785 i2c->master_ctrl |= MXC_F_I2C_MASTER_CTRL_START;
786 }
787 }
788
789 // Fill the FIFO
790 while ((tx_remain > 0) && !(i2c->status & MXC_F_I2C_STATUS_TX_FULL)) {
791 i2c->fifo = *(req->tx_data)++;
792 req->tx_num++;
793 tx_remain--;
794 }
795
796 // Set the TX threshold interrupt level, or restart/stop
797 if (tx_remain) {
798 i2c->tx_ctrl1 = ((i2c->tx_ctrl1 & ~(MXC_F_I2C_TX_CTRL0_TX_THRESH)) | (1 << MXC_F_I2C_TX_CTRL0_TX_THRESH_POS));
799 inten0 |= MXC_F_I2C_INT_EN0_TX_THRESH;
800 }
801 // Set restart or stop if at the end of the transaction since these actions happen at the moment the bit is set.
802 else if (req->restart) {
803 i2c->master_ctrl |= MXC_F_I2C_MASTER_CTRL_RESTART;
804 } else {
805 i2c->master_ctrl |= MXC_F_I2C_MASTER_CTRL_STOP;
806 inten0 |= MXC_F_I2C_INT_EN0_STOP;
807 }
808 }
809
810 inten0 |= (MXC_F_I2C_INT_EN0_DONE | I2C_ERROR);
811 i2c->int_en0 = inten0;
812 }
813
814 /* ************************************************************************** */
I2C_SlaveAsync(mxc_i2c_regs_t * i2c,i2c_req_t * req)815 int I2C_SlaveAsync(mxc_i2c_regs_t *i2c, i2c_req_t *req)
816 {
817 int i2c_num;
818
819 i2c_num = MXC_I2C_GET_IDX(i2c);
820
821 // Make sure the I2C has been initialized
822 if (!(i2c->ctrl & MXC_F_I2C_CTRL_I2C_EN)) {
823 return E_UNINITIALIZED;
824 }
825
826 // Attempt to register this request
827 if (mxc_get_lock((uint32_t*)&states[i2c_num].req, (uint32_t)req) != E_NO_ERROR) {
828 return E_BUSY;
829 }
830
831 states[i2c_num].req = req;
832
833 // Set Slave Address
834 i2c->slave_addr = (req->addr >> 1);
835
836 // Clear the byte counters
837 req->tx_num = 0;
838 req->rx_num = 0;
839
840 // Disable and clear the interrupts
841 i2c->int_en0 = 0;
842 i2c->int_en1 = 0;
843 i2c->int_fl0 = i2c->int_fl0;
844 i2c->int_fl1 = i2c->int_fl1;
845 i2c->int_en0 |= MXC_F_I2C_INT_EN0_ADDR_MATCH;
846
847 return E_NO_ERROR;
848 }
849 /* ************************************************************************** */
I2C_SlaveHandler(mxc_i2c_regs_t * i2c)850 static void I2C_SlaveHandler(mxc_i2c_regs_t *i2c)
851 {
852 uint32_t int0, inten0 = 0;
853 int rx_remain, tx_remain, i2c_num;
854 i2c_req_t *req;
855
856 i2c_num = MXC_I2C_GET_IDX(i2c);
857 req = states[i2c_num].req;
858
859 if ( i2c->int_fl0 & MXC_F_I2C_INT_FL0_ADDR_MATCH ) {
860 i2c->int_fl0 |=MXC_F_I2C_INT_EN0_STOP;
861 }
862
863 // Check for errors
864 int0 = i2c->int_fl0;
865 if (int0 & I2C_ERROR) {
866 i2c->int_en0 = 0;
867 // Calculate the number of bytes sent by the slave
868 req->tx_num = states[i2c_num].num_wr - ((i2c->tx_ctrl1 & MXC_F_I2C_TX_CTRL1_TX_FIFO) >> MXC_F_I2C_TX_CTRL1_TX_FIFO_POS);
869
870 if (!req->sw_autoflush_disable) {
871 // Manually clear the TXFIFO
872 i2c->tx_ctrl0 |= MXC_F_I2C_TX_CTRL0_TX_FLUSH;
873 }
874 states[i2c_num].num_wr = 0;
875 if (req->callback != NULL) {
876 I2C_Recover(i2c);
877 I2C_FreeCallback(i2c_num, E_COMM_ERR);
878 }
879 return;
880 }
881
882 rx_remain = req->rx_len - req->rx_num;
883 tx_remain = req->tx_len - states[i2c_num].num_wr;
884
885 //Check if Master Write has been called and if there is a rx_data buffer
886 if ((i2c->int_fl0 & MXC_F_I2C_INT_FL0_TX_LOCK_OUT) && !(i2c->ctrl & MXC_F_I2C_CTRL_READ)) {
887
888 i2c->int_en0 = 0;
889 if (req->rx_data == NULL) {
890 I2C_Recover(i2c);
891 I2C_FreeCallback(i2c_num, E_NULL_PTR);
892 return;
893 }
894 }
895
896 // Check for DONE interrupt
897 if (int0 & MXC_F_I2C_INT_EN0_DONE) {
898 // Read out any data in the RX FIFO
899 while (rx_remain && !(i2c->status & MXC_F_I2C_STATUS_RX_EMPTY)) {
900 *(req->rx_data)++ = i2c->fifo;
901 req->rx_num++;
902 rx_remain--;
903 }
904
905 // Calculate the number of bytes sent by the slave
906 req->tx_num = states[i2c_num].num_wr - ((i2c->tx_ctrl1 & MXC_F_I2C_TX_CTRL1_TX_FIFO) >> MXC_F_I2C_TX_CTRL1_TX_FIFO_POS);
907
908 if (!req->sw_autoflush_disable) {
909 // Manually clear the TXFIFO
910 i2c->tx_ctrl0 |= MXC_F_I2C_TX_CTRL0_TX_FLUSH;
911 }
912 states[i2c_num].num_wr = 0;
913 i2c->int_en0 = 0;
914 if (req->callback != NULL) {
915 if (i2c->int_fl0 & MXC_F_I2C_INT_FL0_STOP) {
916 I2C_Recover(i2c);
917 } else {
918 i2c->int_fl0 = i2c->int_fl0;
919 i2c->int_fl1 = i2c->int_fl1;
920 }
921 I2C_FreeCallback(i2c_num, E_NO_ERROR);
922 }
923 return;
924 }
925
926 // Clear the interrupts
927 i2c->int_fl0 = int0;
928 if (i2c->ctrl & MXC_F_I2C_CTRL_READ) {
929
930 i2c->int_en0 = 0;
931 if (req->tx_data == NULL) {
932 I2C_Recover(i2c);
933 I2C_FreeCallback(i2c_num, E_NULL_PTR);
934 return;
935 }
936 // Fill the FIFO
937 while ((tx_remain > 0) && !(i2c->status & MXC_F_I2C_STATUS_TX_FULL)) {
938 i2c->fifo = *(req->tx_data)++;
939 states[i2c_num].num_wr++;
940 tx_remain--;
941 }
942
943 // Set the TX threshold interrupt level
944 if (tx_remain) {
945 i2c->tx_ctrl0 = ((i2c->tx_ctrl0 & ~(MXC_F_I2C_TX_CTRL0_TX_THRESH)) | (1 << MXC_F_I2C_TX_CTRL0_TX_THRESH_POS));
946 inten0 |= MXC_F_I2C_INT_EN0_TX_THRESH;
947 }
948
949 } else {
950 // Read out any data in the RX FIFO
951 while (rx_remain && !(i2c->status & MXC_F_I2C_STATUS_RX_EMPTY)) {
952 *(req->rx_data)++ = i2c->fifo;
953 req->rx_num++;
954 rx_remain--;
955 }
956
957 // Set the RX threshold interrupt level
958 if (rx_remain >= (MXC_I2C_FIFO_DEPTH - 1)) {
959 i2c->rx_ctrl0 = ((i2c->rx_ctrl0 & ~(MXC_F_I2C_RX_CTRL0_RX_THRESH)) |
960 (MXC_I2C_FIFO_DEPTH - 1) << MXC_F_I2C_RX_CTRL0_RX_THRESH_POS);
961
962 inten0 |= MXC_F_I2C_INT_EN0_RX_THRESH;
963 }else{
964 i2c->rx_ctrl0 = ((i2c->rx_ctrl0 & ~(MXC_F_I2C_RX_CTRL0_RX_THRESH)) |
965 (rx_remain) << MXC_F_I2C_RX_CTRL0_RX_THRESH_POS);
966
967 inten0 |= MXC_F_I2C_INT_EN0_RX_THRESH;
968 }
969
970 }
971 inten0 |= (MXC_F_I2C_INT_EN0_DONE | I2C_ERROR | MXC_F_I2C_INT_EN0_TX_LOCK_OUT);
972 i2c->int_en0 = inten0;
973 }
974
975 /* ************************************************************************** */
I2C_Handler(mxc_i2c_regs_t * i2c)976 void I2C_Handler(mxc_i2c_regs_t *i2c)
977 {
978 if (i2c->ctrl & MXC_F_I2C_CTRL_MST && i2c->int_fl0) {
979 // Service master interrupts if we're in master mode
980 I2C_MasterHandler(i2c);
981 } else if (i2c->int_fl0 || i2c->int_fl1) {
982 // Service the slave interrupts
983 I2C_SlaveHandler(i2c);
984 }
985 }
986
987 /* ************************************************************************** */
I2C_DrainRX(mxc_i2c_regs_t * i2c)988 void I2C_DrainRX(mxc_i2c_regs_t *i2c)
989 {
990 i2c->rx_ctrl0 |= MXC_F_I2C_RX_CTRL0_RX_FLUSH;
991 }
992
993 /* ************************************************************************** */
I2C_DrainTX(mxc_i2c_regs_t * i2c)994 void I2C_DrainTX(mxc_i2c_regs_t *i2c)
995 {
996 i2c->tx_ctrl0 |= MXC_F_I2C_TX_CTRL0_TX_FLUSH;
997 }
998 /* ************************************************************************* */
I2C_FreeCallback(int i2c_num,int error)999 static void I2C_FreeCallback(int i2c_num, int error)
1000 {
1001 // Save the request
1002 i2c_req_t *temp_req = states[i2c_num].req;
1003
1004 mxc_free_lock((uint32_t*)&states[i2c_num].req);
1005
1006 // Callback if not NULL
1007 if (temp_req->callback != NULL) {
1008 temp_req->callback(temp_req, error);
1009 }
1010 }
1011
1012 /* ************************************************************************* */
I2C_Recover(mxc_i2c_regs_t * i2c)1013 static void I2C_Recover(mxc_i2c_regs_t *i2c)
1014 {
1015 // Disable and clear interrupts
1016 i2c->int_en0 = 0;
1017 i2c->int_en1 = 0;
1018 i2c->int_fl0 = i2c->int_fl0;
1019 i2c->int_fl1 = i2c->int_fl1;
1020 i2c->ctrl = 0;
1021 i2c->ctrl = MXC_F_I2C_CTRL_I2C_EN;
1022 }
1023
1024 /* ************************************************************************* */
I2C_AbortAsync(i2c_req_t * req)1025 int I2C_AbortAsync(i2c_req_t *req)
1026 {
1027 int i2c_num;
1028 mxc_i2c_regs_t *i2c;
1029
1030 // Find the request, set to NULL
1031 for (i2c_num = 0; i2c_num < MXC_I2C_INSTANCES; i2c_num++) {
1032 if (req == states[i2c_num].req) {
1033
1034 i2c = MXC_I2C_GET_I2C(i2c_num);
1035 I2C_Recover(i2c);
1036 I2C_FreeCallback(i2c_num, E_ABORT);
1037
1038 return E_NO_ERROR;
1039 }
1040 }
1041
1042 return E_BAD_PARAM;
1043 }
1044
1045 /* ************************************************************************* */
I2C_SetTimeout(mxc_i2c_regs_t * i2c,int us)1046 int I2C_SetTimeout(mxc_i2c_regs_t *i2c, int us){
1047 uint32_t timeout;
1048 timeout = (PeripheralClock/1000000) * us;
1049 if(timeout > 0xFFFF){
1050 return E_BAD_PARAM;
1051 }
1052 i2c->timeout = timeout;
1053 return E_NO_ERROR;
1054 }
1055
1056 /* ************************************************************************* */
I2C_ClearTimeout(mxc_i2c_regs_t * i2c)1057 void I2C_ClearTimeout (mxc_i2c_regs_t *i2c)
1058 {
1059 i2c->timeout = 0;
1060 }
1061