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