1 /******************************************************************************
2  *
3  * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
4  * Analog Devices, Inc.),
5  * Copyright (C) 2023-2024 Analog Devices, Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************************/
20 
21 #include <stdio.h>
22 #include <stddef.h>
23 #include <stdint.h>
24 #include <stdbool.h>
25 #include "mxc_device.h"
26 #include "mxc_assert.h"
27 #include "mxc_lock.h"
28 #include "mxc_sys.h"
29 #include "mxc_delay.h"
30 #include "i2c_regs.h"
31 #include "i2c.h"
32 #include "i2c_reva.h"
33 #include "dma.h"
34 #include "dma_reva.h"
35 
36 /* **** Variable Declaration **** */
37 typedef struct {
38     mxc_i2c_reva_req_t *req;
39     int master; // 1 for Master, 0 for slave
40     int channelTx; // DMA channel for TX transaction
41     int channelRx; // DMA channel for RX transaction
42     volatile int writeDone; // Write done flag
43     volatile int readDone; // Flag done flag
44     bool dma_initialized; // Check to see whether DMA was initialized
45     mxc_dma_reva_regs_t *dma; // Save DMA Instance
46 } mxc_i2c_reva_req_state_t;
47 
48 static mxc_i2c_reva_req_state_t states[MXC_I2C_INSTANCES];
49 
50 void *AsyncRequests[MXC_I2C_INSTANCES];
51 unsigned int AsyncWritten[MXC_I2C_INSTANCES];
52 unsigned int AsyncRead[MXC_I2C_INSTANCES];
53 
54 /* **** Function Prototypes **** */
55 void MXC_I2C_RevA_AsyncCallback(mxc_i2c_reva_regs_t *i2c, int retVal);
56 void MXC_I2C_RevA_AsyncStop(mxc_i2c_reva_regs_t *i2c);
57 void MXC_I2C_RevA_AbortAsync(mxc_i2c_reva_regs_t *i2c);
58 void MXC_I2C_RevA_MasterAsyncHandler(int i2cNum);
59 int MXC_I2C_RevA_DMAHandler(mxc_i2c_reva_req_t *req);
60 void MXC_I2C_RevA_SlaveAsyncHandler(mxc_i2c_reva_regs_t *i2c, mxc_i2c_reva_slave_handler_t callback,
61                                     uint32_t *int_en, int *retVal);
62 
63 /* ************************************************************************* */
64 /* Control/Configuration functions                                           */
65 /* ************************************************************************* */
MXC_I2C_RevA_Init(mxc_i2c_reva_regs_t * i2c,int masterMode,unsigned int slaveAddr)66 int MXC_I2C_RevA_Init(mxc_i2c_reva_regs_t *i2c, int masterMode, unsigned int slaveAddr)
67 {
68     int err;
69     int8_t i2cNum;
70 
71     if (i2c == NULL) {
72         return E_NULL_PTR;
73     }
74 
75     i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c);
76 
77     if ((err = MXC_I2C_Recover((mxc_i2c_regs_t *)i2c, 16)) != E_NO_ERROR) {
78         return err;
79     }
80 
81     i2c->ctrl |= MXC_F_I2C_REVA_CTRL_EN;
82 
83     MXC_I2C_ClearRXFIFO((mxc_i2c_regs_t *)i2c);
84     MXC_I2C_ClearTXFIFO((mxc_i2c_regs_t *)i2c);
85     // Set the thresholds here and allow the user to change them as needed
86     MXC_I2C_SetTXThreshold((mxc_i2c_regs_t *)i2c, 2); // set TX threshold to 2 bytes
87     MXC_I2C_SetRXThreshold((mxc_i2c_regs_t *)i2c, 6); // set RX threshold to 6 bytes
88 
89     if (!masterMode) {
90         MXC_I2C_SetSlaveAddr((mxc_i2c_regs_t *)i2c, slaveAddr, 0);
91         states[MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c)].master = 0;
92     } else {
93         i2c->ctrl |= MXC_F_I2C_REVA_CTRL_MST_MODE;
94         states[MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c)].master = 1;
95     }
96 
97     // Prepare I2C instance state.
98     states[i2cNum].channelTx = E_NO_DEVICE;
99     states[i2cNum].channelRx = E_NO_DEVICE;
100     states[i2cNum].writeDone = 0;
101     states[i2cNum].readDone = 0;
102     states[i2cNum].dma_initialized = false;
103 
104     return E_NO_ERROR;
105 }
106 
MXC_I2C_RevA_SetSlaveAddr(mxc_i2c_reva_regs_t * i2c,unsigned int slaveAddr,int idx)107 int MXC_I2C_RevA_SetSlaveAddr(mxc_i2c_reva_regs_t *i2c, unsigned int slaveAddr, int idx)
108 {
109     if (i2c == NULL) {
110         return E_NULL_PTR;
111     }
112 
113     if (idx >= (sizeof(i2c->slave_multi) / sizeof(uint32_t))) {
114         return E_NOT_SUPPORTED;
115     }
116 
117     if (slaveAddr > MXC_F_I2C_REVA_SLAVE_MULTI_ADDR) {
118         // Only support addresses up to 10 bits
119         return E_BAD_PARAM;
120     }
121 
122     i2c->slave_multi[idx] = 0;
123 
124     if (slaveAddr > MXC_I2C_REVA_MAX_ADDR_WIDTH) {
125         // Set for 10bit addressing mode
126         i2c->slave_multi[idx] = MXC_F_I2C_REVA_SLAVE_MULTI_EXT_ADDR_EN;
127     }
128 
129     i2c->slave_multi[idx] |= slaveAddr;
130 
131     return E_NO_ERROR;
132 }
133 
MXC_I2C_RevA_Shutdown(mxc_i2c_reva_regs_t * i2c)134 int MXC_I2C_RevA_Shutdown(mxc_i2c_reva_regs_t *i2c)
135 {
136     int8_t i2cNum;
137 
138     if (i2c == NULL) {
139         return E_NULL_PTR;
140     }
141 
142     i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c);
143 
144     i2c->ctrl = 0;
145     i2c->inten0 = 0;
146     i2c->inten1 = 0;
147     i2c->intfl0 = i2c->intfl0;
148     i2c->intfl1 = i2c->intfl1;
149     i2c->rxctrl0 = 0;
150     i2c->rxctrl1 = 0;
151     i2c->txctrl0 = 0;
152     i2c->txctrl1 = 0;
153 
154     states[i2cNum] = (const mxc_i2c_reva_req_state_t){ 0 };
155 
156     MXC_I2C_ClearRXFIFO((mxc_i2c_regs_t *)i2c);
157     MXC_I2C_ClearTXFIFO((mxc_i2c_regs_t *)i2c);
158 
159     if (states[i2cNum].dma_initialized == true) {
160 #if TARGET_NUM == 32665
161         MXC_DMA_DeInit((mxc_dma_regs_t *)(states[i2cNum].dma));
162 #else
163         MXC_DMA_DeInit();
164 #endif
165         // Release any acquired DMA channels.
166         if (states[i2cNum].channelTx >= 0) {
167             MXC_DMA_ReleaseChannel(states[i2cNum].channelTx);
168             states[i2cNum].channelTx = E_NO_DEVICE;
169         }
170         if (states[i2cNum].channelRx >= 0) {
171             MXC_DMA_ReleaseChannel(states[i2cNum].channelRx);
172             states[i2cNum].channelRx = E_NO_DEVICE;
173         }
174     }
175 
176     return E_NO_ERROR;
177 }
178 
MXC_I2C_RevA_SetFrequency(mxc_i2c_reva_regs_t * i2c,unsigned int hz)179 int MXC_I2C_RevA_SetFrequency(mxc_i2c_reva_regs_t *i2c, unsigned int hz)
180 {
181     unsigned int ticksTotal, hiClks, lowClks;
182 
183     if (i2c == NULL) {
184         return E_NULL_PTR;
185     }
186 
187     if (hz > MXC_I2C_REVA_FASTPLUS_SPEED && hz <= MXC_I2C_REVA_HIGH_SPEED) {
188         // Enable high speed mode
189         int hsLowClks, hsHiClks;
190 
191         // Calculate the period of SCL and set up 33% duty cycle
192         ticksTotal = PeripheralClock / hz;
193         hsLowClks = (ticksTotal * 2) / 3 - 1;
194         hsHiClks = ticksTotal / 3 - 1;
195 
196         // For rounding errors, adjust by 1 clock tick
197         if (ticksTotal % 2) {
198             hsHiClks++;
199         }
200 
201         // If we're too slow for high speed, bail out
202         if ((hsHiClks > 0xF) || (hsLowClks > 0xF)) {
203             return E_BAD_PARAM;
204         }
205 
206         hsLowClks = (hsLowClks << MXC_F_I2C_REVA_HSCLK_LO_POS) & MXC_F_I2C_REVA_HSCLK_LO;
207         hsHiClks = (hsHiClks << MXC_F_I2C_REVA_HSCLK_HI_POS) & MXC_F_I2C_REVA_HSCLK_HI;
208 
209         i2c->hsclk = (hsLowClks | hsHiClks);
210 
211         i2c->ctrl |= MXC_F_I2C_REVA_CTRL_HS_EN;
212 
213         hz = MXC_I2C_REVA_FAST_SPEED; // High speed preambles will be sent at 400kHz
214 
215     } else if (hz > MXC_I2C_REVA_HIGH_SPEED) {
216         return E_BAD_PARAM;
217     }
218 
219     // Calculate the period of SCL, 50% duty cycle
220     ticksTotal = PeripheralClock / hz;
221     hiClks = (ticksTotal >> 1) - 1;
222     lowClks = (ticksTotal >> 1) - 1;
223 
224     // Adjust for rounding errors
225     if (ticksTotal % 2) {
226         hiClks++;
227     }
228 
229     // Check for maximum/minimum supported speeds
230     if ((hiClks > MXC_F_I2C_REVA_CLKHI_HI) || (lowClks == 0)) {
231         return E_BAD_PARAM;
232     }
233 
234     i2c->clklo = lowClks & MXC_F_I2C_REVA_CLKLO_LO;
235     i2c->clkhi = hiClks & MXC_F_I2C_REVA_CLKHI_HI;
236 
237     // Return the actual speed set, since it won't be exactly what's requested
238     return MXC_I2C_GetFrequency((mxc_i2c_regs_t *)i2c);
239 }
240 
MXC_I2C_RevA_GetFrequency(mxc_i2c_reva_regs_t * i2c)241 unsigned int MXC_I2C_RevA_GetFrequency(mxc_i2c_reva_regs_t *i2c)
242 {
243     unsigned int sclCycles = 2;
244     // sclCycles Initialized to 2 b/c formula is sclCycles = (lo_clks + 1) + (hi_clks + 1)
245 
246     if (i2c->ctrl & MXC_F_I2C_REVA_CTRL_HS_EN) {
247         // HS-Mode enabled, calculate HS Frequency
248         sclCycles += (i2c->hsclk & MXC_F_I2C_REVA_HSCLK_LO) >> MXC_F_I2C_REVA_HSCLK_LO_POS;
249         sclCycles += (i2c->hsclk & MXC_F_I2C_REVA_HSCLK_HI) >> MXC_F_I2C_REVA_HSCLK_HI_POS;
250     } else {
251         // HS-Mode not enabled, calculate nominal frequency
252         sclCycles += (i2c->clklo & MXC_F_I2C_REVA_CLKLO_LO);
253         sclCycles += (i2c->clkhi & MXC_F_I2C_REVA_CLKHI_HI);
254     }
255 
256     return PeripheralClock / sclCycles;
257 }
258 
MXC_I2C_RevA_ReadyForSleep(mxc_i2c_reva_regs_t * i2c)259 int MXC_I2C_RevA_ReadyForSleep(mxc_i2c_reva_regs_t *i2c)
260 {
261     if (MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c) < 0) {
262         return E_BAD_PARAM;
263     }
264 
265     if (AsyncRequests[MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c)] != NULL) {
266         return E_BUSY;
267     }
268 
269     return E_NO_ERROR;
270 }
271 
MXC_I2C_RevA_SetClockStretching(mxc_i2c_reva_regs_t * i2c,int enable)272 int MXC_I2C_RevA_SetClockStretching(mxc_i2c_reva_regs_t *i2c, int enable)
273 {
274     if (i2c == NULL) {
275         return E_NULL_PTR;
276     }
277 
278     if (enable) {
279         i2c->ctrl &= ~MXC_F_I2C_REVA_CTRL_CLKSTR_DIS;
280     } else {
281         i2c->ctrl |= MXC_F_I2C_REVA_CTRL_CLKSTR_DIS;
282     }
283 
284     return E_NO_ERROR;
285 }
286 
MXC_I2C_RevA_GetClockStretching(mxc_i2c_reva_regs_t * i2c)287 int MXC_I2C_RevA_GetClockStretching(mxc_i2c_reva_regs_t *i2c)
288 {
289     if (i2c == NULL) {
290         return E_NULL_PTR;
291     }
292 
293     return !((i2c->ctrl & MXC_F_I2C_REVA_CTRL_CLKSTR_DIS) >> MXC_F_I2C_REVA_CTRL_CLKSTR_DIS_POS);
294 }
295 
MXC_I2C_RevA_DMA_Init(mxc_i2c_reva_regs_t * i2c,mxc_dma_reva_regs_t * dma,bool use_dma_tx,bool use_dma_rx)296 int MXC_I2C_RevA_DMA_Init(mxc_i2c_reva_regs_t *i2c, mxc_dma_reva_regs_t *dma, bool use_dma_tx,
297                           bool use_dma_rx)
298 {
299     int8_t i2cNum;
300     int8_t rxChannel;
301     int8_t txChannel;
302 
303     if (i2c == NULL || dma == NULL) {
304         return E_NULL_PTR;
305     }
306 
307     i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c);
308 
309     if (states[i2cNum].dma_initialized == false) {
310 #if TARGET_NUM == 32665
311         MXC_DMA_Init((mxc_dma_regs_t *)dma);
312 #else
313         MXC_DMA_Init();
314 #endif
315     }
316 
317     // Release any acquire DMA TX channels before configuring.
318     if (states[i2cNum].channelTx != E_NO_DEVICE) {
319         MXC_DMA_ReleaseChannel(states[i2cNum].channelTx);
320     }
321 
322     // Release any acquire DMA RX channels before configuring.
323     if (states[i2cNum].channelRx != E_NO_DEVICE) {
324         MXC_DMA_ReleaseChannel(states[i2cNum].channelRx);
325     }
326 
327     // Set up I2C DMA TX.
328     if (use_dma_tx == true) {
329 #if TARGET_NUM == 32665
330         txChannel = MXC_DMA_AcquireChannel((mxc_dma_regs_t *)dma);
331 #else
332         txChannel = MXC_DMA_AcquireChannel();
333 #endif
334 
335         // Set Source and Destination Widths.
336         MXC_SETFIELD(dma->ch[txChannel].ctrl, MXC_F_DMA_REVA_CTRL_SRCWD,
337                      (MXC_DMA_WIDTH_BYTE << MXC_F_DMA_REVA_CTRL_SRCWD_POS));
338         MXC_SETFIELD(dma->ch[txChannel].ctrl, MXC_F_DMA_REVA_CTRL_DSTWD,
339                      (MXC_DMA_WIDTH_BYTE << MXC_F_DMA_REVA_CTRL_DSTWD_POS));
340 
341         // Set Source and Destination Increment.
342         MXC_SETFIELD(dma->ch[txChannel].ctrl, MXC_F_DMA_REVA_CTRL_SRCINC,
343                      (1 << MXC_F_DMA_REVA_CTRL_SRCINC_POS));
344         MXC_SETFIELD(dma->ch[txChannel].ctrl, MXC_F_DMA_REVA_CTRL_DSTINC,
345                      (0 << MXC_F_DMA_REVA_CTRL_DSTINC_POS));
346 
347         if (states[i2cNum].master) {
348             MXC_DMA_SetCallback(txChannel, MXC_I2C_RevA_DMACallback);
349         } else {
350             MXC_DMA_SetCallback(txChannel, NULL);
351         }
352 
353         MXC_DMA_EnableInt(txChannel);
354         MXC_DMA_SetChannelInterruptEn(txChannel, 0, 1);
355 
356         states[i2cNum].channelTx = txChannel;
357     }
358 
359     // Set up I2C DMA RX.
360     if (use_dma_rx == true) {
361 #if TARGET_NUM == 32665
362         rxChannel = MXC_DMA_AcquireChannel((mxc_dma_regs_t *)dma);
363 #else
364         rxChannel = MXC_DMA_AcquireChannel();
365 #endif
366 
367         // Set Source and Destination Widths.
368         MXC_SETFIELD(dma->ch[rxChannel].ctrl, MXC_F_DMA_REVA_CTRL_SRCWD,
369                      (MXC_DMA_WIDTH_BYTE << MXC_F_DMA_REVA_CTRL_SRCWD_POS));
370         MXC_SETFIELD(dma->ch[rxChannel].ctrl, MXC_F_DMA_REVA_CTRL_DSTWD,
371                      (MXC_DMA_WIDTH_BYTE << MXC_F_DMA_REVA_CTRL_DSTWD_POS));
372 
373         // Set Source and Destination Increment.
374         MXC_SETFIELD(dma->ch[rxChannel].ctrl, MXC_F_DMA_REVA_CTRL_SRCINC,
375                      (0 << MXC_F_DMA_REVA_CTRL_SRCINC_POS));
376         MXC_SETFIELD(dma->ch[rxChannel].ctrl, MXC_F_DMA_REVA_CTRL_DSTINC,
377                      (1 << MXC_F_DMA_REVA_CTRL_DSTINC_POS));
378 
379         if (states[i2cNum].master) {
380             MXC_DMA_SetCallback(rxChannel, MXC_I2C_RevA_DMACallback);
381         } else {
382             MXC_DMA_SetCallback(rxChannel, NULL);
383         }
384 
385         MXC_DMA_EnableInt(rxChannel);
386         MXC_DMA_SetChannelInterruptEn(rxChannel, 0, 1);
387 
388         states[i2cNum].channelRx = rxChannel;
389     }
390 
391     states[i2cNum].dma_initialized = true;
392     states[i2cNum].dma = dma;
393 
394     return E_NO_ERROR;
395 }
396 
MXC_I2C_RevA_DMA_GetTXChannel(mxc_i2c_reva_regs_t * i2c)397 int MXC_I2C_RevA_DMA_GetTXChannel(mxc_i2c_reva_regs_t *i2c)
398 {
399     int i2cNum;
400 
401     if (i2c == NULL) {
402         return E_NULL_PTR;
403     }
404 
405     i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c);
406 
407     return states[i2cNum].channelTx;
408 }
409 
MXC_I2C_RevA_DMA_GetRXChannel(mxc_i2c_reva_regs_t * i2c)410 int MXC_I2C_RevA_DMA_GetRXChannel(mxc_i2c_reva_regs_t *i2c)
411 {
412     int i2cNum;
413 
414     if (i2c == NULL) {
415         return E_NULL_PTR;
416     }
417 
418     i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c);
419 
420     return states[i2cNum].channelRx;
421 }
422 
MXC_I2C_RevA_DMA_SetRequestSelect(mxc_i2c_reva_regs_t * i2c,mxc_dma_reva_regs_t * dma,uint32_t txReqSel,uint32_t rxReqSel)423 int MXC_I2C_RevA_DMA_SetRequestSelect(mxc_i2c_reva_regs_t *i2c, mxc_dma_reva_regs_t *dma,
424                                       uint32_t txReqSel, uint32_t rxReqSel)
425 {
426     int i2cNum;
427     uint32_t txChannel;
428     uint32_t rxChannel;
429 
430     if (i2c == NULL || dma == NULL) {
431         return E_NULL_PTR;
432     }
433 
434     i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c);
435 
436     txChannel = states[i2cNum].channelTx;
437     rxChannel = states[i2cNum].channelRx;
438 
439     // This function will overwrite the current DMA TX/RX Request Selects.
440     if (txReqSel != -1) {
441         MXC_SETFIELD(dma->ch[txChannel].ctrl, MXC_F_DMA_REVA_CTRL_REQUEST, txReqSel);
442     }
443 
444     if (rxReqSel != -1) {
445         MXC_SETFIELD(dma->ch[rxChannel].ctrl, MXC_F_DMA_REVA_CTRL_REQUEST, rxReqSel);
446     }
447 
448     return E_NO_ERROR;
449 }
450 
451 /* ************************************************************************* */
452 /* Low-level functions                                                       */
453 /* ************************************************************************* */
MXC_I2C_RevA_Start(mxc_i2c_reva_regs_t * i2c)454 int MXC_I2C_RevA_Start(mxc_i2c_reva_regs_t *i2c)
455 {
456     if (i2c == NULL) {
457         return E_NULL_PTR;
458     }
459 
460     // If we have an incomplete transfer, we need to do a restart
461     if (i2c->mstctrl & MXC_F_I2C_REVA_MSTCTRL_START) {
462         i2c->mstctrl |= MXC_F_I2C_REVA_MSTCTRL_RESTART;
463     } else {
464         i2c->mstctrl |= MXC_F_I2C_REVA_MSTCTRL_START; // No check for start generation
465     }
466 
467     return E_NO_ERROR;
468 }
469 
MXC_I2C_RevA_Stop(mxc_i2c_reva_regs_t * i2c)470 int MXC_I2C_RevA_Stop(mxc_i2c_reva_regs_t *i2c)
471 {
472     if (i2c == NULL) {
473         return E_NULL_PTR;
474     }
475 
476     i2c->mstctrl |= MXC_F_I2C_REVA_MSTCTRL_STOP;
477 
478     while (i2c->mstctrl & MXC_F_I2C_REVA_MSTCTRL_STOP) {}
479 
480     return E_NO_ERROR;
481 }
482 
MXC_I2C_RevA_WriteByte(mxc_i2c_reva_regs_t * i2c,unsigned char byte)483 int MXC_I2C_RevA_WriteByte(mxc_i2c_reva_regs_t *i2c, unsigned char byte)
484 {
485     if (i2c == NULL) {
486         return E_NULL_PTR;
487     }
488 
489     if (!(i2c->status & MXC_F_I2C_REVA_STATUS_TX_EM)) {
490         return E_OVERFLOW;
491     }
492 
493     // I'm depending on an interrupt flag here
494     // This might cause issues with the transaction level functions to come
495     MXC_I2C_ClearFlags((mxc_i2c_regs_t *)i2c, MXC_I2C_REVA_INTFL0_MASK, MXC_I2C_REVA_INTFL1_MASK);
496     i2c->fifo = byte;
497 
498     while (!(i2c->status & MXC_F_I2C_REVA_STATUS_TX_EM)) {}
499 
500     return i2c->intfl0 & MXC_F_I2C_REVA_INTFL0_DATA_ERR;
501 }
502 
MXC_I2C_RevA_ReadByte(mxc_i2c_reva_regs_t * i2c,unsigned char * byte,int ack)503 int MXC_I2C_RevA_ReadByte(mxc_i2c_reva_regs_t *i2c, unsigned char *byte, int ack)
504 {
505     if ((i2c == NULL) || (byte == NULL)) {
506         return E_NULL_PTR;
507     }
508 
509     if (i2c->status & MXC_F_I2C_REVA_STATUS_RX_EM) {
510         return E_UNDERFLOW;
511     }
512 
513     *byte = (uint8_t)(i2c->fifo & MXC_F_I2C_REVA_FIFO_DATA);
514 
515     if (ack) {
516         i2c->ctrl &= ~MXC_F_I2C_REVA_CTRL_IRXM_ACK;
517     } else {
518         i2c->ctrl |= MXC_F_I2C_REVA_CTRL_IRXM_ACK;
519     }
520 
521     return E_NO_ERROR;
522 }
523 
MXC_I2C_RevA_ReadByteInteractive(mxc_i2c_reva_regs_t * i2c,unsigned char * byte,mxc_i2c_reva_getAck_t getAck)524 int MXC_I2C_RevA_ReadByteInteractive(mxc_i2c_reva_regs_t *i2c, unsigned char *byte,
525                                      mxc_i2c_reva_getAck_t getAck)
526 {
527     if ((i2c == NULL) || (byte == NULL)) {
528         return E_NULL_PTR;
529     }
530 
531     if (!(i2c->status & MXC_F_I2C_REVA_STATUS_RX_EM)) {
532         return E_UNDERFLOW;
533     }
534 
535     *byte = (uint8_t)(i2c->fifo & MXC_F_I2C_REVA_FIFO_DATA);
536 
537     if (getAck == NULL) {
538         i2c->ctrl &= ~MXC_F_I2C_REVA_CTRL_IRXM_ACK_POS;
539     } else {
540         i2c->ctrl |= (!!getAck((mxc_i2c_reva_regs_t *)i2c, *byte))
541                      << MXC_F_I2C_REVA_CTRL_IRXM_ACK_POS;
542     }
543 
544     return E_NO_ERROR;
545 }
546 
MXC_I2C_RevA_Write(mxc_i2c_reva_regs_t * i2c,unsigned char * bytes,unsigned int * len)547 int MXC_I2C_RevA_Write(mxc_i2c_reva_regs_t *i2c, unsigned char *bytes, unsigned int *len)
548 {
549     int notAcked = 0;
550     unsigned written = 0;
551 
552     if (i2c == NULL) {
553         return E_NULL_PTR;
554     }
555 
556     if ((bytes == NULL) || (len == NULL)) {
557         return E_NULL_PTR;
558     }
559 
560     for (; written < *len; written++) {
561         int retVal = MXC_I2C_WriteByte((mxc_i2c_regs_t *)i2c, bytes[written]);
562 
563         if (retVal >= 0) {
564             notAcked += retVal;
565         } else {
566             *len = written;
567             return retVal;
568         }
569     }
570 
571     *len = written;
572     notAcked = (notAcked > 0) ? 1 : 0;
573     return notAcked;
574 }
575 
MXC_I2C_RevA_Read(mxc_i2c_reva_regs_t * i2c,unsigned char * bytes,unsigned int * len,int ack)576 int MXC_I2C_RevA_Read(mxc_i2c_reva_regs_t *i2c, unsigned char *bytes, unsigned int *len, int ack)
577 {
578     unsigned read = 0;
579 
580     if (i2c == NULL) {
581         return E_NULL_PTR;
582     }
583 
584     if ((bytes == NULL) || (len == NULL)) {
585         return E_NULL_PTR;
586     }
587 
588     for (; read < *len - 1; read++) {
589         int retVal = MXC_I2C_ReadByte((mxc_i2c_regs_t *)i2c, &(bytes[read]), 1);
590 
591         if (retVal != E_NO_ERROR) {
592             *len = read;
593             return retVal;
594         }
595     }
596 
597     read++;
598     *len = read;
599     return MXC_I2C_ReadByte((mxc_i2c_regs_t *)i2c, &(bytes[read]), ack);
600 }
601 
MXC_I2C_RevA_ReadRXFIFO(mxc_i2c_reva_regs_t * i2c,volatile unsigned char * bytes,unsigned int len)602 int MXC_I2C_RevA_ReadRXFIFO(mxc_i2c_reva_regs_t *i2c, volatile unsigned char *bytes,
603                             unsigned int len)
604 {
605     unsigned read = 0;
606 
607     if ((i2c == NULL) || (bytes == NULL)) {
608         return E_NULL_PTR;
609     }
610 
611     while ((len > read) && (!(i2c->status & MXC_F_I2C_REVA_STATUS_RX_EM))) {
612         bytes[read++] = i2c->fifo;
613     }
614 
615     return read;
616 }
617 
MXC_I2C_RevA_ReadRXFIFODMA(mxc_i2c_reva_regs_t * i2c,unsigned char * bytes,unsigned int len,mxc_dma_regs_t * dma)618 int MXC_I2C_RevA_ReadRXFIFODMA(mxc_i2c_reva_regs_t *i2c, unsigned char *bytes, unsigned int len,
619                                mxc_dma_regs_t *dma)
620 {
621     uint8_t i2cNum;
622     mxc_dma_srcdst_t srcdst;
623 
624     if ((i2c == NULL) || (bytes == NULL)) {
625         return E_NULL_PTR;
626     }
627 
628     i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c);
629 
630     if (states[i2cNum].channelRx == E_NO_DEVICE) {
631         return E_BAD_STATE;
632     }
633 
634     srcdst.ch = states[i2cNum].channelRx;
635     srcdst.dest = bytes;
636     srcdst.len = len;
637 
638     MXC_DMA_SetSrcDst(srcdst);
639 
640     MXC_DMA_Start(states[i2cNum].channelRx);
641     i2c->dma |= MXC_F_I2C_REVA_DMA_RX_EN;
642 
643     return E_NO_ERROR;
644 }
645 
MXC_I2C_RevA_GetRXFIFOAvailable(mxc_i2c_reva_regs_t * i2c)646 int MXC_I2C_RevA_GetRXFIFOAvailable(mxc_i2c_reva_regs_t *i2c)
647 {
648     if (i2c == NULL) {
649         return E_NULL_PTR;
650     }
651 
652     return (i2c->rxctrl1 & MXC_F_I2C_REVA_RXCTRL1_LVL) >> MXC_F_I2C_REVA_RXCTRL1_LVL_POS;
653 }
654 
MXC_I2C_RevA_WriteTXFIFO(mxc_i2c_reva_regs_t * i2c,volatile unsigned char * bytes,unsigned int len)655 int MXC_I2C_RevA_WriteTXFIFO(mxc_i2c_reva_regs_t *i2c, volatile unsigned char *bytes,
656                              unsigned int len)
657 {
658     unsigned written = 0;
659 
660     if ((i2c == NULL) || (bytes == NULL)) {
661         return E_NULL_PTR;
662     }
663 
664     while ((len > written) && (!(i2c->status & MXC_F_I2C_REVA_STATUS_TX_FULL))) {
665         i2c->fifo = bytes[written++];
666     }
667 
668     return written;
669 }
670 
MXC_I2C_RevA_WriteTXFIFODMA(mxc_i2c_reva_regs_t * i2c,unsigned char * bytes,unsigned int len,mxc_dma_regs_t * dma)671 int MXC_I2C_RevA_WriteTXFIFODMA(mxc_i2c_reva_regs_t *i2c, unsigned char *bytes, unsigned int len,
672                                 mxc_dma_regs_t *dma)
673 {
674     int8_t i2cNum;
675     mxc_dma_srcdst_t srcdst;
676 
677     if ((i2c == NULL) || (bytes == NULL)) {
678         return E_NULL_PTR;
679     }
680 
681     i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c);
682 
683     i2c->mstctrl |= MXC_F_I2C_REVA_MSTCTRL_START;
684 
685     if (states[i2cNum].channelTx == E_NO_DEVICE) {
686         return E_BAD_STATE;
687     }
688 
689     srcdst.ch = states[i2cNum].channelTx;
690     srcdst.source = bytes;
691     srcdst.len = len;
692 
693     MXC_DMA_SetSrcDst(srcdst);
694 
695     MXC_DMA_Start(states[i2cNum].channelTx);
696     i2c->dma |= MXC_F_I2C_REVA_DMA_TX_EN;
697 
698     return E_NO_ERROR;
699 }
700 
MXC_I2C_RevA_GetTXFIFOAvailable(mxc_i2c_reva_regs_t * i2c)701 int MXC_I2C_RevA_GetTXFIFOAvailable(mxc_i2c_reva_regs_t *i2c)
702 {
703     if (i2c == NULL) {
704         return E_NULL_PTR;
705     }
706 
707     int txFIFOlen = (i2c->fifolen & MXC_F_I2C_REVA_FIFOLEN_TX_DEPTH) >>
708                     MXC_F_I2C_REVA_FIFOLEN_TX_DEPTH_POS;
709     return txFIFOlen -
710            ((i2c->txctrl1 & MXC_F_I2C_REVA_TXCTRL1_LVL) >> MXC_F_I2C_REVA_TXCTRL1_LVL_POS);
711 }
712 
MXC_I2C_RevA_ClearRXFIFO(mxc_i2c_reva_regs_t * i2c)713 void MXC_I2C_RevA_ClearRXFIFO(mxc_i2c_reva_regs_t *i2c)
714 {
715     i2c->rxctrl0 |= MXC_F_I2C_REVA_RXCTRL0_FLUSH;
716 
717     while (i2c->rxctrl0 & MXC_F_I2C_REVA_RXCTRL0_FLUSH) {}
718 }
719 
MXC_I2C_RevA_ClearTXFIFO(mxc_i2c_reva_regs_t * i2c)720 void MXC_I2C_RevA_ClearTXFIFO(mxc_i2c_reva_regs_t *i2c)
721 {
722     i2c->txctrl0 |= MXC_F_I2C_REVA_TXCTRL0_FLUSH;
723 
724     while (i2c->txctrl0 & MXC_F_I2C_REVA_TXCTRL0_FLUSH) {}
725 }
726 
MXC_I2C_RevA_GetFlags(mxc_i2c_reva_regs_t * i2c,unsigned int * flags0,unsigned int * flags1)727 int MXC_I2C_RevA_GetFlags(mxc_i2c_reva_regs_t *i2c, unsigned int *flags0, unsigned int *flags1)
728 {
729     if (i2c == NULL) {
730         return E_NULL_PTR;
731     }
732 
733     if ((flags0 == NULL) || (flags1 == NULL)) {
734         return E_BAD_PARAM;
735     }
736 
737     *flags0 = i2c->intfl0;
738     *flags1 = i2c->intfl1;
739 
740     return E_NO_ERROR;
741 }
742 
MXC_I2C_RevA_ClearFlags(mxc_i2c_reva_regs_t * i2c,unsigned int flags0,unsigned int flags1)743 void MXC_I2C_RevA_ClearFlags(mxc_i2c_reva_regs_t *i2c, unsigned int flags0, unsigned int flags1)
744 {
745     i2c->intfl0 = flags0;
746     i2c->intfl1 = flags1;
747 }
748 
MXC_I2C_RevA_EnableInt(mxc_i2c_reva_regs_t * i2c,unsigned int flags0,unsigned int flags1)749 void MXC_I2C_RevA_EnableInt(mxc_i2c_reva_regs_t *i2c, unsigned int flags0, unsigned int flags1)
750 {
751     i2c->inten0 |= flags0;
752     i2c->inten1 |= flags1;
753 }
754 
MXC_I2C_RevA_DisableInt(mxc_i2c_reva_regs_t * i2c,unsigned int flags0,unsigned int flags1)755 void MXC_I2C_RevA_DisableInt(mxc_i2c_reva_regs_t *i2c, unsigned int flags0, unsigned int flags1)
756 {
757     i2c->inten0 &= ~flags0;
758     i2c->inten1 &= ~flags1;
759 }
760 
MXC_I2C_RevA_Recover(mxc_i2c_reva_regs_t * i2c,unsigned int retries)761 int MXC_I2C_RevA_Recover(mxc_i2c_reva_regs_t *i2c, unsigned int retries)
762 {
763     int err;
764     unsigned int i;
765 
766     if (i2c == NULL) {
767         return E_NULL_PTR;
768     }
769 
770     err = E_COMM_ERR;
771 
772     i2c->ctrl |= MXC_F_I2C_REVA_CTRL_EN;
773     int swBit = i2c->ctrl & MXC_F_I2C_REVA_CTRL_BB_MODE;
774 
775     if (i2c == NULL) {
776         return E_NULL_PTR;
777     }
778 
779     i2c->ctrl |= MXC_F_I2C_REVA_CTRL_BB_MODE;
780 
781     // Follow the procedure detailed in the header file
782     // Delay 10uS between each step to give the line/slaves time to react
783     for (i = 0; i < retries; i++) {
784         MXC_Delay(10);
785         i2c->ctrl &= ~MXC_F_I2C_REVA_CTRL_SCL_OUT;
786 
787         MXC_Delay(10);
788 
789         if (i2c->ctrl & MXC_F_I2C_REVA_CTRL_SCL) {
790             i2c->ctrl |= MXC_F_I2C_REVA_CTRL_SCL_OUT | MXC_F_I2C_REVA_CTRL_SDA_OUT;
791             continue; // Give up and try again
792         }
793 
794         MXC_Delay(10);
795         i2c->ctrl &= ~MXC_F_I2C_REVA_CTRL_SDA_OUT;
796 
797         MXC_Delay(10);
798 
799         if (i2c->ctrl & MXC_F_I2C_REVA_CTRL_SDA) {
800             i2c->ctrl |= MXC_F_I2C_REVA_CTRL_SCL_OUT | MXC_F_I2C_REVA_CTRL_SDA_OUT;
801             continue; // Give up and try again
802         }
803 
804         MXC_Delay(10);
805         i2c->ctrl |= MXC_F_I2C_REVA_CTRL_SDA_OUT;
806 
807         MXC_Delay(10);
808 
809         if (!(i2c->ctrl & MXC_F_I2C_REVA_CTRL_SDA)) {
810             i2c->ctrl |= MXC_F_I2C_REVA_CTRL_SCL_OUT | MXC_F_I2C_REVA_CTRL_SDA_OUT;
811             continue; // Give up and try again
812         }
813 
814         MXC_Delay(10);
815         i2c->ctrl |= MXC_F_I2C_REVA_CTRL_SCL_OUT;
816 
817         MXC_Delay(10);
818 
819         if (i2c->ctrl & MXC_F_I2C_REVA_CTRL_SCL) {
820             err = E_NO_ERROR; // We have control
821             break;
822         }
823     }
824 
825     if (swBit == 0) {
826         i2c->ctrl &= ~MXC_F_I2C_REVA_CTRL_BB_MODE;
827     }
828 
829     i2c->ctrl &= ~MXC_F_I2C_REVA_CTRL_EN;
830 
831     return err;
832 }
833 
MXC_I2C_RevA_EnablePreload(mxc_i2c_reva_regs_t * i2c)834 void MXC_I2C_RevA_EnablePreload(mxc_i2c_reva_regs_t *i2c)
835 {
836     i2c->txctrl0 |= MXC_F_I2C_REVA_TXCTRL0_PRELOAD_MODE;
837 }
838 
MXC_I2C_RevA_DisablePreload(mxc_i2c_reva_regs_t * i2c)839 void MXC_I2C_RevA_DisablePreload(mxc_i2c_reva_regs_t *i2c)
840 {
841     i2c->txctrl0 &= ~MXC_F_I2C_REVA_TXCTRL0_PRELOAD_MODE;
842 }
843 
MXC_I2C_RevA_EnableGeneralCall(mxc_i2c_reva_regs_t * i2c)844 void MXC_I2C_RevA_EnableGeneralCall(mxc_i2c_reva_regs_t *i2c)
845 {
846     i2c->ctrl |= MXC_F_I2C_REVA_CTRL_GC_ADDR_EN;
847 }
848 
MXC_I2C_RevA_DisableGeneralCall(mxc_i2c_reva_regs_t * i2c)849 void MXC_I2C_RevA_DisableGeneralCall(mxc_i2c_reva_regs_t *i2c)
850 {
851     i2c->ctrl &= ~MXC_F_I2C_REVA_CTRL_GC_ADDR_EN;
852 }
853 
MXC_I2C_RevA_SetTimeout(mxc_i2c_reva_regs_t * i2c,unsigned int timeout)854 void MXC_I2C_RevA_SetTimeout(mxc_i2c_reva_regs_t *i2c, unsigned int timeout)
855 {
856     i2c->timeout |= (timeout & 0xFFFF);
857 }
858 
MXC_I2C_RevA_GetTimeout(mxc_i2c_reva_regs_t * i2c)859 unsigned int MXC_I2C_RevA_GetTimeout(mxc_i2c_reva_regs_t *i2c)
860 {
861     return (i2c->timeout & 0xFFFF);
862 }
863 
864 /* ************************************************************************* */
865 /* Transaction level functions                                               */
866 /* ************************************************************************* */
867 
MXC_I2C_RevA_MasterTransaction(mxc_i2c_reva_req_t * req)868 int MXC_I2C_RevA_MasterTransaction(mxc_i2c_reva_req_t *req)
869 {
870     mxc_i2c_reva_regs_t *i2c = req->i2c; // Save off pointer for faster access
871     unsigned int written = 0;
872     unsigned int read = 0;
873 
874     if (req->addr > MXC_I2C_REVA_MAX_ADDR_WIDTH) {
875         return E_NOT_SUPPORTED;
876     }
877 
878     if (MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c) < 0) {
879         return E_BAD_PARAM;
880     }
881 
882     if (!(i2c->ctrl & MXC_F_I2C_REVA_CTRL_MST_MODE)) {
883         return E_BAD_STATE;
884     }
885 
886     // if(!read | write)
887     //  Start
888     //  send addr w/ write bit
889     // if(Write)
890     //  send tx_len data
891     //  return if error (or NACK)
892     // if(Read)
893     //  if(Write)
894     //   send restart
895     //  else
896     //   send start
897     //  send addr w/ read bit
898     //  read rx_len bytes acking all
899     // stop or restart
900     // return good or error
901 
902     MXC_I2C_ClearFlags((mxc_i2c_regs_t *)i2c, MXC_I2C_REVA_INTFL0_MASK,
903                        MXC_I2C_REVA_INTFL1_MASK); // Clear all I2C Interrupts
904     MXC_I2C_ClearTXFIFO((mxc_i2c_regs_t *)i2c);
905     MXC_I2C_ClearRXFIFO((mxc_i2c_regs_t *)i2c);
906     i2c->inten0 = 0;
907     i2c->inten1 = 0;
908 
909     if ((req->rx_len == 0) || (req->tx_len != 0)) {
910         // Load the slave address with write bit set
911         i2c->fifo = (req->addr << 1) & ~0x1;
912         i2c->mstctrl |= MXC_F_I2C_REVA_MSTCTRL_START;
913     }
914 
915     while (req->tx_len > written) {
916         if (i2c->intfl0 & MXC_F_I2C_REVA_INTFL0_TX_THD) {
917             written += MXC_I2C_WriteTXFIFO((mxc_i2c_regs_t *)i2c, &req->tx_buf[written],
918                                            req->tx_len - written);
919             i2c->intfl0 = MXC_F_I2C_REVA_INTFL0_TX_THD;
920         }
921 
922         if (i2c->intfl0 & MXC_I2C_REVA_ERROR) {
923             req->tx_len = written;
924             MXC_I2C_Stop((mxc_i2c_regs_t *)i2c);
925             return E_COMM_ERR;
926         }
927     }
928 
929     MXC_I2C_ClearFlags((mxc_i2c_regs_t *)i2c,
930                        MXC_F_I2C_REVA_INTFL0_DONE | MXC_F_I2C_REVA_INTFL0_RX_THD, 0);
931 
932     if (req->rx_len != 0) {
933         if (req->rx_len > MXC_I2C_REVA_MAX_FIFO_TRANSACTION) {
934             i2c->rxctrl1 = 0;
935         } else {
936             i2c->rxctrl1 = req->rx_len; // 0 for 256, otherwise number of bytes to read
937         }
938 
939         MXC_I2C_Start((mxc_i2c_regs_t *)i2c); // Start or Restart as needed
940 
941         while (i2c->mstctrl & MXC_F_I2C_REVA_MSTCTRL_RESTART) {}
942 
943         i2c->fifo = (req->addr << 1) | 0x1; // Load slave address with read bit.
944     }
945 
946     while (req->rx_len > read) {
947         if (i2c->intfl0 & (MXC_F_I2C_REVA_INTFL0_RX_THD | MXC_F_I2C_REVA_INTFL0_DONE)) {
948             read +=
949                 MXC_I2C_ReadRXFIFO((mxc_i2c_regs_t *)i2c, &req->rx_buf[read], req->rx_len - read);
950             i2c->intfl0 = MXC_F_I2C_REVA_INTFL0_RX_THD;
951         }
952 
953         if (i2c->intfl0 & MXC_I2C_REVA_ERROR) {
954             req->rx_len = read;
955             MXC_I2C_Stop((mxc_i2c_regs_t *)i2c);
956             return E_COMM_ERR;
957         }
958 
959         if ((i2c->intfl0 & MXC_F_I2C_REVA_INTFL0_DONE) && (req->rx_len > read) &&
960             (MXC_I2C_RevA_GetRXFIFOAvailable(i2c) == 0)) {
961             if ((req->rx_len - read) > MXC_I2C_REVA_MAX_FIFO_TRANSACTION) {
962                 i2c->rxctrl1 = 0;
963             } else {
964                 i2c->rxctrl1 = (req->rx_len - read); // 0 for 256, otherwise number of bytes to read
965             }
966 
967             i2c->mstctrl |= MXC_F_I2C_REVA_MSTCTRL_RESTART;
968             i2c->intfl0 = MXC_F_I2C_REVA_INTFL0_DONE;
969             i2c->fifo = (req->addr << 1) | 0x1; // Load slave address with read bit.
970         }
971     }
972 
973     if (req->restart) {
974         i2c->mstctrl |= MXC_F_I2C_REVA_MSTCTRL_RESTART;
975     } else {
976         i2c->mstctrl |= MXC_F_I2C_REVA_MSTCTRL_STOP;
977 
978         while (!(i2c->intfl0 & MXC_F_I2C_REVA_INTFL0_STOP)) {}
979         // Wait for Transaction to finish
980     }
981 
982     while (!(i2c->intfl0 & MXC_F_I2C_REVA_INTFL0_DONE)) {}
983     // Wait for Transaction to finish
984 
985     i2c->intfl0 = MXC_F_I2C_REVA_INTFL0_DONE | MXC_F_I2C_REVA_INTFL0_STOP;
986 
987     if (i2c->intfl0 & MXC_I2C_REVA_ERROR) {
988         return E_COMM_ERR;
989     }
990 
991     return E_NO_ERROR;
992 }
993 
MXC_I2C_RevA_MasterTransactionAsync(mxc_i2c_reva_req_t * req)994 int MXC_I2C_RevA_MasterTransactionAsync(mxc_i2c_reva_req_t *req)
995 {
996     int i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)(req->i2c));
997     mxc_i2c_reva_regs_t *i2c = req->i2c;
998 
999     if (i2cNum < 0) {
1000         return E_BAD_PARAM;
1001     }
1002 
1003     if (!(i2c->ctrl & MXC_F_I2C_REVA_CTRL_MST_MODE)) {
1004         return E_BAD_STATE;
1005     }
1006 
1007     if (AsyncRequests[i2cNum] == NULL) {
1008         if (req->addr > MXC_I2C_REVA_MAX_ADDR_WIDTH) {
1009             return E_NOT_SUPPORTED;
1010         }
1011 
1012         AsyncRequests[i2cNum] = (void *)req;
1013         AsyncWritten[i2cNum] = 0;
1014         AsyncRead[i2cNum] = 0;
1015         MXC_I2C_ClearFlags((mxc_i2c_regs_t *)i2c, MXC_I2C_REVA_INTFL0_MASK,
1016                            MXC_I2C_REVA_INTFL1_MASK); // Clear all I2C Interrupts
1017         MXC_I2C_ClearTXFIFO((mxc_i2c_regs_t *)i2c);
1018         MXC_I2C_ClearRXFIFO((mxc_i2c_regs_t *)i2c);
1019 
1020         i2c->inten0 = MXC_I2C_REVA_ERROR;
1021 
1022         if (req->tx_len) {
1023             i2c->fifo = (req->addr << 1) & ~0x1; // Load the slave address with write bit set
1024         } else if (req->rx_len) {
1025             i2c->fifo = (req->addr << 1) | 0x1; // Load the slave address with read bit set
1026 
1027             /* Set the number of bytes to read */
1028             if (req->rx_len > MXC_I2C_REVA_MAX_FIFO_TRANSACTION) {
1029                 i2c->rxctrl1 = 0;
1030             } else {
1031                 i2c->rxctrl1 = req->rx_len; // 0 for 256, otherwise number of bytes to read
1032             }
1033 
1034             /* Enable RX Threshold interrupt for when the FIFO is full */
1035             i2c->inten0 |= (MXC_F_I2C_REVA_INTEN0_RX_THD | MXC_F_I2C_REVA_INTEN0_DONE);
1036         } else {
1037             /* Must have tx_len and/or rx_len */
1038             return E_BAD_PARAM;
1039         }
1040 
1041         MXC_I2C_Start((mxc_i2c_regs_t *)i2c);
1042 
1043         /* Fill the FIFO as nessary */
1044         MXC_I2C_RevA_MasterAsyncHandler(i2cNum);
1045 
1046         return E_NO_ERROR;
1047     } else {
1048         return E_BUSY;
1049     }
1050 }
1051 
MXC_I2C_RevA_MasterTransactionDMA(mxc_i2c_reva_req_t * req,mxc_dma_regs_t * dma)1052 int MXC_I2C_RevA_MasterTransactionDMA(mxc_i2c_reva_req_t *req, mxc_dma_regs_t *dma)
1053 {
1054     int error;
1055     int8_t i2cNum;
1056 
1057     mxc_i2c_reva_regs_t *i2c = req->i2c; // Save off pointer for faster access
1058     i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c);
1059 
1060     if (req->addr > MXC_I2C_REVA_MAX_ADDR_WIDTH) {
1061         return E_NOT_SUPPORTED;
1062     }
1063 
1064     if (i2cNum < 0) {
1065         return E_BAD_PARAM;
1066     }
1067 
1068     if (!(i2c->ctrl & MXC_F_I2C_REVA_CTRL_MST_MODE)) {
1069         return E_BAD_STATE;
1070     }
1071 
1072     if (req->rx_len > MXC_I2C_REVA_MAX_FIFO_TRANSACTION) {
1073         return E_BAD_PARAM;
1074     }
1075 
1076     MXC_I2C_ClearFlags((mxc_i2c_regs_t *)i2c, MXC_I2C_REVA_INTFL0_MASK,
1077                        MXC_I2C_REVA_INTFL1_MASK); // Clear all I2C Interrupts
1078     MXC_I2C_ClearTXFIFO((mxc_i2c_regs_t *)i2c);
1079     MXC_I2C_ClearRXFIFO((mxc_i2c_regs_t *)i2c);
1080 
1081     MXC_I2C_SetTXThreshold((mxc_i2c_regs_t *)i2c, 2);
1082     MXC_I2C_SetRXThreshold((mxc_i2c_regs_t *)i2c, 1);
1083 
1084     states[i2cNum].req = req;
1085     states[i2cNum].writeDone = 0;
1086     states[i2cNum].readDone = 0;
1087 
1088     // If MXC_I2C_DMA_Init(...) was not already called, then configure both DMA TX/RXchannels by default.
1089     if (states[i2cNum].dma_initialized == false) {
1090         error = MXC_I2C_DMA_Init((mxc_i2c_regs_t *)i2c, (mxc_dma_regs_t *)dma, true, true);
1091         if (error != E_NO_ERROR) {
1092             return error;
1093         }
1094     }
1095 
1096     error = MXC_I2C_DMA_SetRequestSelect((mxc_i2c_regs_t *)i2c, req->tx_buf, req->rx_buf);
1097     if (error != E_NO_ERROR) {
1098         return error;
1099     }
1100 
1101     //tx
1102     if ((req->tx_buf != NULL) && !(states[i2cNum].writeDone)) {
1103         i2c->fifo = ((req->addr) << 1) & ~0x1; // Load the slave address with write bit set
1104 
1105 #if TARGET_NUM == 32665
1106         MXC_I2C_WriteTXFIFODMA((mxc_i2c_regs_t *)i2c, req->tx_buf, req->tx_len, NULL, dma);
1107 #else
1108         MXC_I2C_WriteTXFIFODMA((mxc_i2c_regs_t *)i2c, req->tx_buf, req->tx_len, NULL);
1109 #endif
1110     } else {
1111         states[i2cNum].writeDone = 1;
1112     }
1113 
1114     if (req->rx_buf != NULL) {
1115         while (states[i2cNum].writeDone != 1) {}
1116         //Ensure DMA transmission has finished before attempting to receive
1117 
1118         if ((states[i2cNum].writeDone) && (!states[i2cNum].readDone)) {
1119             if (req->rx_len > MXC_I2C_REVA_MAX_FIFO_TRANSACTION) {
1120                 i2c->rxctrl1 = 0;
1121             } else {
1122                 i2c->rxctrl1 = req->rx_len; // 0 for 256, otherwise number of bytes to read
1123             }
1124 
1125             MXC_I2C_Start((mxc_i2c_regs_t *)i2c); // Start or Restart as needed
1126 
1127             while (i2c->mstctrl & MXC_F_I2C_REVA_MSTCTRL_RESTART) {}
1128 
1129             i2c->fifo = ((req->addr) << 1) | 0x1; // Load the slave address with write bit set
1130 
1131 #if TARGET_NUM == 32665
1132             MXC_I2C_ReadRXFIFODMA((mxc_i2c_regs_t *)i2c, req->rx_buf, req->rx_len, NULL, dma);
1133 #else
1134             MXC_I2C_ReadRXFIFODMA((mxc_i2c_regs_t *)i2c, req->rx_buf, req->rx_len, NULL);
1135 #endif
1136         }
1137     } else {
1138         states[i2cNum].readDone = 1;
1139     }
1140 
1141     return E_NO_ERROR;
1142 }
1143 
MXC_I2C_RevA_DMACallback(int ch,int error)1144 void MXC_I2C_RevA_DMACallback(int ch, int error)
1145 {
1146     mxc_i2c_reva_req_t *temp_req;
1147 
1148     for (int i = 0; i < MXC_I2C_INSTANCES; i++) {
1149         if (states[i].channelTx == ch) {
1150             //save the request
1151             temp_req = states[i].req;
1152             states[i].writeDone = 1;
1153 
1154             if (states[i].readDone) {
1155                 if (temp_req->restart) {
1156                     (temp_req->i2c)->mstctrl |= MXC_F_I2C_REVA_MSTCTRL_RESTART;
1157                 } else {
1158                     (temp_req->i2c)->mstctrl |= MXC_F_I2C_REVA_MSTCTRL_STOP;
1159                 }
1160 
1161                 // Callback if not NULL
1162                 if (temp_req->callback != NULL) {
1163                     temp_req->callback(temp_req, E_NO_ERROR);
1164                 }
1165             }
1166         } else if (states[i].channelRx == ch) {
1167             //save the request
1168             states[i].readDone = 1;
1169             temp_req = states[i].req;
1170 
1171             if (states[i].writeDone) {
1172                 if (temp_req->restart) {
1173                     (temp_req->i2c)->mstctrl |= MXC_F_I2C_REVA_MSTCTRL_RESTART;
1174                 } else {
1175                     (temp_req->i2c)->mstctrl |= MXC_F_I2C_REVA_MSTCTRL_STOP;
1176                 }
1177 
1178                 // Callback if not NULL
1179                 if (temp_req->callback != NULL) {
1180                     temp_req->callback(temp_req, E_NO_ERROR);
1181                 }
1182             }
1183         }
1184     }
1185 }
1186 
MXC_I2C_RevA_SlaveTransaction(mxc_i2c_reva_regs_t * i2c,mxc_i2c_reva_slave_handler_t callback,uint32_t interruptCheck)1187 int MXC_I2C_RevA_SlaveTransaction(mxc_i2c_reva_regs_t *i2c, mxc_i2c_reva_slave_handler_t callback,
1188                                   uint32_t interruptCheck)
1189 {
1190     int retVal = E_NO_ERROR;
1191 
1192     uint32_t int_en[2];
1193     int_en[0] = interruptCheck;
1194     int_en[1] = 0;
1195 
1196     if (MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c) < 0) {
1197         return E_BAD_PARAM;
1198     }
1199 
1200     if (i2c->ctrl & MXC_F_I2C_REVA_CTRL_MST_MODE) {
1201         return E_BAD_STATE;
1202     }
1203 
1204     MXC_I2C_ClearFlags((mxc_i2c_regs_t *)i2c, MXC_I2C_REVA_INTFL0_MASK,
1205                        MXC_I2C_REVA_INTFL1_MASK); // Clear all I2C Interrupts
1206     MXC_I2C_ClearTXFIFO((mxc_i2c_regs_t *)i2c);
1207     MXC_I2C_ClearRXFIFO((mxc_i2c_regs_t *)i2c);
1208 
1209     // Callback called on
1210     // Slave Address Match (distinguish read/write)
1211     // RX Threshold
1212     // TX Threshold
1213     // Done
1214     // TX Underflow
1215     // RX Overflow
1216     //
1217     // Event Codes
1218     // I2C_EVT_MASTER_WR
1219     // I2C_EVT_MASTER_RD
1220     // I2C_EVT_RX_THRESH
1221     // I2C_EVT_TX_THRESH
1222     // I2C_EVT_TRANS_COMP
1223     // I2C_EVT_UNDERFLOW
1224     // I2C_EVT_OVERFLOW
1225 
1226     while (int_en[0] > 0 || int_en[1] > 0) {
1227         MXC_I2C_RevA_SlaveAsyncHandler(i2c, callback, int_en, &retVal);
1228     }
1229 
1230     return retVal;
1231 }
1232 
MXC_I2C_RevA_SlaveTransactionAsync(mxc_i2c_reva_regs_t * i2c,mxc_i2c_reva_slave_handler_t callback,uint32_t interruptCheck)1233 int MXC_I2C_RevA_SlaveTransactionAsync(mxc_i2c_reva_regs_t *i2c,
1234                                        mxc_i2c_reva_slave_handler_t callback,
1235                                        uint32_t interruptCheck)
1236 {
1237     int i2cnum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c);
1238 
1239     if (i2cnum < 0) {
1240         return E_BAD_PARAM;
1241     }
1242 
1243     if (i2c->ctrl & MXC_F_I2C_REVA_CTRL_MST_MODE) {
1244         return E_BAD_STATE;
1245     }
1246 
1247     if (AsyncRequests[i2cnum] != NULL) {
1248         return E_BUSY;
1249     }
1250 
1251     MXC_I2C_ClearFlags((mxc_i2c_regs_t *)i2c, MXC_I2C_REVA_INTFL0_MASK,
1252                        MXC_I2C_REVA_INTFL1_MASK); // Clear all I2C Interrupts
1253     MXC_I2C_ClearTXFIFO((mxc_i2c_regs_t *)i2c);
1254     MXC_I2C_ClearRXFIFO((mxc_i2c_regs_t *)i2c);
1255     MXC_I2C_SetTXThreshold((mxc_i2c_regs_t *)i2c, 1); // set TX threshold to 2 bytes
1256     MXC_I2C_SetRXThreshold((mxc_i2c_regs_t *)i2c, 1); // set RX threshold to 6 bytes
1257     AsyncRequests[i2cnum] = (void *)callback;
1258 
1259     i2c->inten0 = interruptCheck;
1260 
1261     return E_NO_ERROR;
1262 }
1263 
MXC_I2C_RevA_SetRXThreshold(mxc_i2c_reva_regs_t * i2c,unsigned int numBytes)1264 int MXC_I2C_RevA_SetRXThreshold(mxc_i2c_reva_regs_t *i2c, unsigned int numBytes)
1265 {
1266     unsigned int rxFIFOlen = (i2c->fifolen & MXC_F_I2C_REVA_FIFOLEN_RX_DEPTH) >>
1267                              MXC_F_I2C_REVA_FIFOLEN_RX_DEPTH_POS;
1268 
1269     if (numBytes > rxFIFOlen) {
1270         return E_BAD_PARAM;
1271     }
1272 
1273     i2c->rxctrl0 = (i2c->rxctrl0 & ~MXC_F_I2C_REVA_RXCTRL0_THD_LVL) |
1274                    (numBytes << MXC_F_I2C_REVA_RXCTRL0_THD_LVL_POS);
1275     return E_NO_ERROR;
1276 }
1277 
MXC_I2C_RevA_GetRXThreshold(mxc_i2c_reva_regs_t * i2c)1278 unsigned int MXC_I2C_RevA_GetRXThreshold(mxc_i2c_reva_regs_t *i2c)
1279 {
1280     return (i2c->rxctrl0 & MXC_F_I2C_REVA_RXCTRL0_THD_LVL) >> MXC_F_I2C_REVA_RXCTRL0_THD_LVL_POS;
1281 }
1282 
MXC_I2C_RevA_SetTXThreshold(mxc_i2c_reva_regs_t * i2c,unsigned int numBytes)1283 int MXC_I2C_RevA_SetTXThreshold(mxc_i2c_reva_regs_t *i2c, unsigned int numBytes)
1284 {
1285     unsigned int txFIFOlen = (i2c->fifolen & MXC_F_I2C_REVA_FIFOLEN_TX_DEPTH) >>
1286                              MXC_F_I2C_REVA_FIFOLEN_TX_DEPTH_POS;
1287 
1288     if (numBytes > txFIFOlen) {
1289         return E_BAD_PARAM;
1290     }
1291 
1292     i2c->txctrl0 = (i2c->txctrl0 & ~MXC_F_I2C_REVA_TXCTRL0_THD_LVL) |
1293                    (numBytes << MXC_F_I2C_REVA_TXCTRL0_THD_LVL_POS);
1294     return E_NO_ERROR;
1295 }
1296 
MXC_I2C_RevA_GetTXThreshold(mxc_i2c_reva_regs_t * i2c)1297 unsigned int MXC_I2C_RevA_GetTXThreshold(mxc_i2c_reva_regs_t *i2c)
1298 {
1299     return (i2c->txctrl0 & MXC_F_I2C_REVA_TXCTRL0_THD_LVL) >> MXC_F_I2C_REVA_TXCTRL0_THD_LVL_POS;
1300 }
1301 
MXC_I2C_RevA_AsyncCallback(mxc_i2c_reva_regs_t * i2c,int retVal)1302 void MXC_I2C_RevA_AsyncCallback(mxc_i2c_reva_regs_t *i2c, int retVal)
1303 {
1304     // Don't need to check for return value as this function is not accessible to user
1305     // i2c is already cheked for NULL from where this function is being called
1306     mxc_i2c_reva_req_t *req =
1307         (mxc_i2c_reva_req_t *)AsyncRequests[MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c)];
1308 
1309     if (req->callback != NULL) {
1310         req->callback(req, retVal);
1311     }
1312 }
1313 
MXC_I2C_RevA_AsyncStop(mxc_i2c_reva_regs_t * i2c)1314 void MXC_I2C_RevA_AsyncStop(mxc_i2c_reva_regs_t *i2c)
1315 {
1316     /* Disable and clear interrupts */
1317     i2c->inten0 = 0;
1318     i2c->inten1 = 0;
1319 
1320     i2c->intfl0 = i2c->intfl0;
1321     i2c->intfl1 = i2c->intfl1;
1322 
1323     // Don't need to check for return value as this function is not accessible to user
1324     // i2c is already cheked for NULL from where this function is being called
1325     AsyncRequests[MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c)] = NULL;
1326 }
1327 
MXC_I2C_RevA_AbortAsync(mxc_i2c_reva_regs_t * i2c)1328 void MXC_I2C_RevA_AbortAsync(mxc_i2c_reva_regs_t *i2c)
1329 {
1330     // Don't need to check for return value as this function is not accessible to user
1331     // i2c is already cheked for NULL from where this function is being called
1332     MXC_I2C_RevA_AsyncCallback(i2c, E_ABORT);
1333     MXC_I2C_RevA_AsyncStop(i2c);
1334 }
1335 
MXC_I2C_RevA_MasterAsyncHandler(int i2cNum)1336 void MXC_I2C_RevA_MasterAsyncHandler(int i2cNum)
1337 {
1338     unsigned int written = AsyncWritten[i2cNum];
1339     unsigned int read = AsyncRead[i2cNum];
1340     mxc_i2c_reva_regs_t *i2c = (mxc_i2c_reva_regs_t *)MXC_I2C_GET_BASE(i2cNum);
1341     mxc_i2c_reva_req_t *req = (mxc_i2c_reva_req_t *)AsyncRequests[i2cNum];
1342 
1343     /* Check for errors */
1344     if (i2c->intfl0 & MXC_I2C_REVA_ERROR) {
1345         /* Clear and disable interrupts */
1346         i2c->intfl0 = i2c->intfl0;
1347         i2c->intfl1 = i2c->intfl1;
1348         i2c->inten0 = 0;
1349         i2c->inten1 = 0;
1350 
1351         MXC_I2C_Stop((mxc_i2c_regs_t *)i2c);
1352         MXC_I2C_RevA_AsyncCallback(i2c, E_COMM_ERR);
1353         MXC_I2C_RevA_AsyncStop(i2c);
1354 
1355         return;
1356     }
1357 
1358     /* Write data to the TX FIFO */
1359     if (req->tx_len > written) {
1360         if (i2c->intfl0 & MXC_F_I2C_REVA_INTFL0_TX_THD) {
1361             written += MXC_I2C_WriteTXFIFO((mxc_i2c_regs_t *)i2c, &req->tx_buf[written],
1362                                            req->tx_len - written);
1363             i2c->intfl0 = MXC_F_I2C_REVA_INTFL0_TX_THD;
1364         }
1365 
1366         /* Enable the TX Threshold interrupt if we still need to write to the TX FIFO */
1367         if (written < req->tx_len) {
1368             i2c->inten0 |= MXC_F_I2C_REVA_INTEN0_TX_THD;
1369         } else {
1370             i2c->inten0 &= ~(MXC_F_I2C_REVA_INTEN0_TX_THD);
1371         }
1372 
1373         /* Send a restart if we're reading after writing */
1374         if ((req->tx_len == written) && (req->rx_len)) {
1375             i2c->mstctrl |= MXC_F_I2C_REVA_MSTCTRL_RESTART;
1376             i2c->intfl0 = MXC_F_I2C_REVA_INTFL0_DONE;
1377             i2c->inten0 |= (MXC_F_I2C_REVA_INTEN0_DONE);
1378         }
1379     }
1380 
1381     /* Read data in the RX FIFO */
1382     if (req->rx_len > read) {
1383         if (i2c->intfl0 & (MXC_F_I2C_REVA_INTFL0_RX_THD | MXC_F_I2C_REVA_INTFL0_DONE)) {
1384             read +=
1385                 MXC_I2C_ReadRXFIFO((mxc_i2c_regs_t *)i2c, &req->rx_buf[read], req->rx_len - read);
1386             i2c->intfl0 = MXC_F_I2C_REVA_INTFL0_RX_THD;
1387         }
1388     }
1389 
1390     /* Done writing, still reading */
1391     if ((req->tx_len == written) && (req->rx_len - read) &&
1392         (i2c->intfl0 & MXC_F_I2C_REVA_INTFL0_DONE)) {
1393         i2c->intfl0 = MXC_F_I2C_REVA_INTFL0_DONE;
1394 
1395         /* First done interrupt after completing writes to the TX FIFO */
1396         if (read == 0) {
1397             i2c->fifo = (req->addr << 1) | 0x1; // Load slave address with read bit.
1398         }
1399 
1400         /* Set the number of bytes to read */
1401         if ((req->rx_len - read) > MXC_I2C_REVA_MAX_FIFO_TRANSACTION) {
1402             i2c->rxctrl1 = 0;
1403         } else {
1404             i2c->rxctrl1 = (req->rx_len - read); // 0 for 256, otherwise number of bytes to read
1405         }
1406 
1407         /* Enable RX Threshold interrupt for when the FIFO is full */
1408         if (read < req->rx_len) {
1409             i2c->inten0 |= (MXC_F_I2C_REVA_INTEN0_RX_THD | MXC_F_I2C_REVA_INTEN0_DONE);
1410         } else {
1411             i2c->inten0 &= ~(MXC_F_I2C_REVA_INTEN0_RX_THD | MXC_F_I2C_REVA_INTEN0_DONE);
1412         }
1413     }
1414 
1415     /* Done reading and writing */
1416     if ((req->tx_len == written) && (req->rx_len == read)) {
1417         /* Disable and clear interrupts */
1418         i2c->inten0 = 0;
1419         i2c->inten1 = 0;
1420         i2c->intfl0 = i2c->intfl0;
1421         i2c->intfl1 = i2c->intfl1;
1422 
1423         /* Send a restart or stop at the end of the transaction */
1424         if (req->restart) {
1425             i2c->mstctrl |= MXC_F_I2C_REVA_MSTCTRL_RESTART;
1426         } else {
1427             i2c->mstctrl |= MXC_F_I2C_REVA_MSTCTRL_STOP;
1428         }
1429 
1430         /* Call the callback */
1431         MXC_I2C_RevA_AsyncCallback(i2c, E_NO_ERROR);
1432 
1433         /* Clear the async state */
1434         MXC_I2C_RevA_AsyncStop(i2c);
1435 
1436     } else {
1437         AsyncWritten[i2cNum] = written;
1438         AsyncRead[i2cNum] = read;
1439     }
1440 }
1441 
MXC_I2C_RevA_SlaveAsyncHandler(mxc_i2c_reva_regs_t * i2c,mxc_i2c_reva_slave_handler_t callback,uint32_t * int_en,int * retVal)1442 void MXC_I2C_RevA_SlaveAsyncHandler(mxc_i2c_reva_regs_t *i2c, mxc_i2c_reva_slave_handler_t callback,
1443                                     uint32_t *int_en, int *retVal)
1444 {
1445     uint32_t tFlags = i2c->intfl0;
1446     *retVal = E_NO_ERROR;
1447 
1448     // Check for errors
1449     if (tFlags & MXC_I2C_REVA_ERROR) {
1450         // Error occurred, notify callback function and end transaction
1451         *retVal = E_COMM_ERR;
1452 
1453         if (callback != NULL) {
1454             callback(i2c, MXC_I2C_REVA_EVT_TRANS_COMP, retVal);
1455         }
1456 
1457         MXC_I2C_RevA_ClearFlags(i2c, MXC_I2C_REVA_INTFL0_MASK,
1458                                 MXC_I2C_REVA_INTFL1_MASK); // clear all i2c interrupts
1459         MXC_I2C_RevA_ClearTXFIFO(i2c);
1460         MXC_I2C_RevA_ClearRXFIFO(i2c);
1461         int_en[0] = 0;
1462         int_en[1] = 0;
1463         AsyncRequests[MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c)] = NULL;
1464     }
1465 
1466     // Check whether data is available if we received an interrupt occurred while receiving
1467     if (int_en[0] & MXC_F_I2C_REVA_INTFL0_RX_THD || int_en[1] & MXC_F_I2C_REVA_INTFL1_RX_OV) {
1468         if (tFlags & MXC_F_I2C_REVA_INTFL0_RX_THD) {
1469             if (callback != NULL) {
1470                 callback(i2c, MXC_I2C_REVA_EVT_RX_THRESH, NULL);
1471             }
1472 
1473             i2c->intfl0 = MXC_F_I2C_REVA_INTFL0_RX_THD;
1474         }
1475 
1476         if (i2c->intfl1 & MXC_F_I2C_REVA_INTFL1_RX_OV) {
1477             if (callback != NULL) {
1478                 callback(i2c, MXC_I2C_REVA_EVT_OVERFLOW, NULL);
1479             }
1480 
1481             i2c->intfl1 = MXC_F_I2C_REVA_INTFL1_RX_OV;
1482         }
1483     }
1484 
1485     // Check whether TX FIFO needs to be refilled if interrupt ocurred while transmitting
1486     if (int_en[0] & (MXC_F_I2C_REVA_INTFL0_TX_THD | MXC_F_I2C_REVA_INTFL0_TX_LOCKOUT) ||
1487         int_en[1] & MXC_F_I2C_REVA_INTFL1_TX_UN) {
1488         if (tFlags & MXC_F_I2C_REVA_INTFL0_TX_THD) {
1489             if (callback != NULL) {
1490                 callback(i2c, MXC_I2C_REVA_EVT_TX_THRESH, NULL);
1491             }
1492 
1493             i2c->intfl0 = MXC_F_I2C_REVA_INTFL0_TX_THD;
1494         }
1495 
1496         if (i2c->intfl1 & MXC_F_I2C_REVA_INTFL1_TX_UN) {
1497             if (callback != NULL) {
1498                 callback(i2c, MXC_I2C_REVA_EVT_UNDERFLOW, NULL);
1499             }
1500 
1501             i2c->intfl1 = MXC_F_I2C_REVA_INTFL1_TX_UN;
1502         }
1503 
1504         if (tFlags & MXC_F_I2C_REVA_INTFL0_TX_LOCKOUT) {
1505             *retVal = E_NO_ERROR;
1506 
1507             if (callback != NULL) {
1508                 callback(i2c, MXC_I2C_REVA_EVT_TRANS_COMP, retVal);
1509             }
1510 
1511             i2c->intfl0 = MXC_F_I2C_REVA_INTFL0_TX_LOCKOUT;
1512             int_en[0] = 0;
1513             int_en[1] = 0;
1514             AsyncRequests[MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c)] = NULL;
1515         }
1516     }
1517 
1518     // Check if transaction completed or restart occurred
1519     if (int_en[0] & MXC_F_I2C_REVA_INTFL0_DONE) {
1520         if (tFlags & MXC_F_I2C_REVA_INTFL0_STOP) {
1521             // Stop/NACK condition occurred, transaction complete
1522             *retVal = E_NO_ERROR;
1523 
1524             if (callback != NULL) {
1525                 callback(i2c, MXC_I2C_REVA_EVT_TRANS_COMP, retVal);
1526             }
1527 
1528             i2c->intfl0 = MXC_F_I2C_REVA_INTFL0_STOP;
1529             int_en[0] = 0;
1530             int_en[1] = 0;
1531             AsyncRequests[MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c)] = NULL;
1532         } else if (tFlags & MXC_F_I2C_REVA_INTFL0_DONE) {
1533             // Restart detected, re-arm address match interrupt
1534             i2c->intfl0 = MXC_F_I2C_REVA_INTFL0_DONE;
1535             int_en[0] = MXC_F_I2C_REVA_INTFL0_ADDR_MATCH;
1536         }
1537     }
1538 
1539     // Check for address match interrupt
1540     if (int_en[0] & MXC_F_I2C_REVA_INTFL0_ADDR_MATCH) {
1541         if (tFlags & MXC_F_I2C_REVA_INTFL0_ADDR_MATCH) {
1542             // Address match occurred, prepare for transaction
1543             if (tFlags & MXC_F_I2C_REVA_INTFL0_STOP && !(tFlags & MXC_F_I2C_REVA_INTFL0_DONE)) {
1544                 // Clear stop flag if it was asserted in a previous transaction
1545                 i2c->intfl0 = MXC_F_I2C_REVA_INTFL0_STOP;
1546             }
1547 
1548             if (i2c->ctrl & MXC_F_I2C_REVA_CTRL_READ) {
1549                 // Read request received from the master
1550                 if (callback != NULL) {
1551                     callback(i2c, MXC_I2C_REVA_EVT_MASTER_RD, NULL);
1552                 }
1553 
1554                 i2c->intfl0 = MXC_F_I2C_REVA_INTFL0_RD_ADDR_MATCH;
1555                 i2c->intfl0 = MXC_F_I2C_REVA_INTFL0_ADDR_MATCH;
1556                 i2c->intfl0 = MXC_F_I2C_REVA_INTFL0_TX_LOCKOUT;
1557 
1558                 int_en[0] = MXC_F_I2C_REVA_INTFL0_TX_THD | MXC_F_I2C_REVA_INTFL0_TX_LOCKOUT |
1559                             MXC_F_I2C_REVA_INTFL0_DONE | MXC_I2C_REVA_ERROR;
1560                 int_en[1] = MXC_F_I2C_REVA_INTFL1_TX_UN;
1561             } else {
1562                 // Write request received from the master
1563                 if (callback != NULL) {
1564                     callback(i2c, MXC_I2C_REVA_EVT_MASTER_WR, NULL);
1565                 }
1566 
1567                 i2c->intfl0 = MXC_F_I2C_REVA_INTFL0_WR_ADDR_MATCH;
1568                 i2c->intfl0 = MXC_F_I2C_REVA_INTFL0_ADDR_MATCH;
1569                 int_en[0] = MXC_F_I2C_REVA_INTFL0_RX_THD | MXC_F_I2C_REVA_INTFL0_DONE |
1570                             MXC_I2C_REVA_ERROR;
1571                 int_en[1] = MXC_F_I2C_REVA_INTFL1_RX_OV;
1572             }
1573         }
1574     }
1575 }
1576 
MXC_I2C_RevA_AsyncHandler(mxc_i2c_reva_regs_t * i2c,uint32_t interruptCheck)1577 void MXC_I2C_RevA_AsyncHandler(mxc_i2c_reva_regs_t *i2c, uint32_t interruptCheck)
1578 {
1579     int i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c);
1580     int slaveRetVal;
1581     uint32_t int_en[2];
1582 
1583     if (i2cNum < 0) {
1584         return;
1585     }
1586 
1587     if (i2c->ctrl & MXC_F_I2C_REVA_CTRL_MST_MODE) {
1588         MXC_I2C_RevA_MasterAsyncHandler(i2cNum);
1589     } else {
1590         mxc_i2c_reva_slave_handler_t callback = (mxc_i2c_reva_slave_handler_t)AsyncRequests[i2cNum];
1591 
1592         int_en[0] = i2c->inten0;
1593         int_en[1] = i2c->inten1;
1594 
1595         MXC_I2C_RevA_SlaveAsyncHandler(i2c, callback, int_en, &slaveRetVal);
1596 
1597         i2c->inten0 = int_en[0];
1598         i2c->inten1 = int_en[1];
1599     }
1600 }
1601