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