1 /*
2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
3 * Copyright 2016-2017 NXP
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * o Redistributions of source code must retain the above copyright notice, this list
9 * of conditions and the following disclaimer.
10 *
11 * o Redistributions in binary form must reproduce the above copyright notice, this
12 * list of conditions and the following disclaimer in the documentation and/or
13 * other materials provided with the distribution.
14 *
15 * o Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "fsl_i2c_edma.h"
32
33 /*******************************************************************************
34 * Definitions
35 ******************************************************************************/
36
37 /*<! @breif Structure definition for i2c_master_edma_private_handle_t. The structure is private. */
38 typedef struct _i2c_master_edma_private_handle
39 {
40 I2C_Type *base;
41 i2c_master_edma_handle_t *handle;
42 } i2c_master_edma_private_handle_t;
43
44 /*! @brief i2c master DMA transfer state. */
45 enum _i2c_master_dma_transfer_states
46 {
47 kIdleState = 0x0U, /*!< I2C bus idle. */
48 kTransferDataState = 0x1U, /*!< 7-bit address check state. */
49 };
50
51 /*! @brief Common sets of flags used by the driver. */
52 enum _i2c_flag_constants
53 {
54 /*! All flags which are cleared by the driver upon starting a transfer. */
55 #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
56 kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag | kI2C_StartDetectFlag | kI2C_StopDetectFlag,
57 #elif defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT
58 kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag | kI2C_StopDetectFlag,
59 #else
60 kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag,
61 #endif
62 };
63
64 /*******************************************************************************
65 * Prototypes
66 ******************************************************************************/
67
68 /*!
69 * @brief EDMA callback for I2C master EDMA driver.
70 *
71 * @param handle EDMA handler for I2C master EDMA driver
72 * @param userData user param passed to the callback function
73 */
74 static void I2C_MasterTransferCallbackEDMA(edma_handle_t *handle, void *userData, bool transferDone, uint32_t tcds);
75
76 /*!
77 * @brief Check and clear status operation.
78 *
79 * @param base I2C peripheral base address.
80 * @param status current i2c hardware status.
81 * @retval kStatus_Success No error found.
82 * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost.
83 * @retval kStatus_I2C_Nak Received Nak error.
84 */
85 static status_t I2C_CheckAndClearError(I2C_Type *base, uint32_t status);
86
87 /*!
88 * @brief EDMA config for I2C master driver.
89 *
90 * @param base I2C peripheral base address.
91 * @param handle pointer to i2c_master_edma_handle_t structure which stores the transfer state
92 */
93 static void I2C_MasterTransferEDMAConfig(I2C_Type *base, i2c_master_edma_handle_t *handle);
94
95 /*!
96 * @brief Set up master transfer, send slave address and sub address(if any), wait until the
97 * wait until address sent status return.
98 *
99 * @param base I2C peripheral base address.
100 * @param handle pointer to i2c_master_edma_handle_t structure which stores the transfer state
101 * @param xfer pointer to i2c_master_transfer_t structure
102 */
103 static status_t I2C_InitTransferStateMachineEDMA(I2C_Type *base,
104 i2c_master_edma_handle_t *handle,
105 i2c_master_transfer_t *xfer);
106
107 /*!
108 * @brief Get the I2C instance from peripheral base address.
109 *
110 * @param base I2C peripheral base address.
111 * @return I2C instance.
112 */
113 extern uint32_t I2C_GetInstance(I2C_Type *base);
114
115 /*******************************************************************************
116 * Variables
117 ******************************************************************************/
118
119 /*<! Private handle only used for internally. */
120 static i2c_master_edma_private_handle_t s_edmaPrivateHandle[FSL_FEATURE_SOC_I2C_COUNT];
121
122 /*******************************************************************************
123 * Codes
124 ******************************************************************************/
125
I2C_MasterTransferCallbackEDMA(edma_handle_t * handle,void * userData,bool transferDone,uint32_t tcds)126 static void I2C_MasterTransferCallbackEDMA(edma_handle_t *handle, void *userData, bool transferDone, uint32_t tcds)
127 {
128 i2c_master_edma_private_handle_t *i2cPrivateHandle = (i2c_master_edma_private_handle_t *)userData;
129 status_t result = kStatus_Success;
130
131 /* Disable DMA. */
132 I2C_EnableDMA(i2cPrivateHandle->base, false);
133
134 /* Send stop if kI2C_TransferNoStop flag is not asserted. */
135 if (!(i2cPrivateHandle->handle->transfer.flags & kI2C_TransferNoStopFlag))
136 {
137 if (i2cPrivateHandle->handle->transfer.direction == kI2C_Read)
138 {
139 /* Change to send NAK at the last byte. */
140 i2cPrivateHandle->base->C1 |= I2C_C1_TXAK_MASK;
141
142 /* Wait the last data to be received. */
143 while (!(i2cPrivateHandle->base->S & kI2C_TransferCompleteFlag))
144 {
145 }
146
147 /* Send stop signal. */
148 result = I2C_MasterStop(i2cPrivateHandle->base);
149
150 /* Read the last data byte. */
151 *(i2cPrivateHandle->handle->transfer.data + i2cPrivateHandle->handle->transfer.dataSize - 1) =
152 i2cPrivateHandle->base->D;
153 }
154 else
155 {
156 /* Wait the last data to be sent. */
157 while (!(i2cPrivateHandle->base->S & kI2C_TransferCompleteFlag))
158 {
159 }
160
161 /* Send stop signal. */
162 result = I2C_MasterStop(i2cPrivateHandle->base);
163 }
164 }
165 else
166 {
167 if (i2cPrivateHandle->handle->transfer.direction == kI2C_Read)
168 {
169 /* Change to send NAK at the last byte. */
170 i2cPrivateHandle->base->C1 |= I2C_C1_TXAK_MASK;
171
172 /* Wait the last data to be received. */
173 while (!(i2cPrivateHandle->base->S & kI2C_TransferCompleteFlag))
174 {
175 }
176
177 /* Change direction to send. */
178 i2cPrivateHandle->base->C1 |= I2C_C1_TX_MASK;
179
180 /* Read the last data byte. */
181 *(i2cPrivateHandle->handle->transfer.data + i2cPrivateHandle->handle->transfer.dataSize - 1) =
182 i2cPrivateHandle->base->D;
183 }
184 }
185
186 i2cPrivateHandle->handle->state = kIdleState;
187
188 if (i2cPrivateHandle->handle->completionCallback)
189 {
190 i2cPrivateHandle->handle->completionCallback(i2cPrivateHandle->base, i2cPrivateHandle->handle, result,
191 i2cPrivateHandle->handle->userData);
192 }
193 }
194
I2C_CheckAndClearError(I2C_Type * base,uint32_t status)195 static status_t I2C_CheckAndClearError(I2C_Type *base, uint32_t status)
196 {
197 status_t result = kStatus_Success;
198
199 /* Check arbitration lost. */
200 if (status & kI2C_ArbitrationLostFlag)
201 {
202 /* Clear arbitration lost flag. */
203 base->S = kI2C_ArbitrationLostFlag;
204 result = kStatus_I2C_ArbitrationLost;
205 }
206 /* Check NAK */
207 else if (status & kI2C_ReceiveNakFlag)
208 {
209 result = kStatus_I2C_Nak;
210 }
211 else
212 {
213 }
214
215 return result;
216 }
217
I2C_InitTransferStateMachineEDMA(I2C_Type * base,i2c_master_edma_handle_t * handle,i2c_master_transfer_t * xfer)218 static status_t I2C_InitTransferStateMachineEDMA(I2C_Type *base,
219 i2c_master_edma_handle_t *handle,
220 i2c_master_transfer_t *xfer)
221 {
222 assert(handle);
223 assert(xfer);
224
225 status_t result = kStatus_Success;
226
227 if (handle->state != kIdleState)
228 {
229 return kStatus_I2C_Busy;
230 }
231 else
232 {
233 i2c_direction_t direction = xfer->direction;
234
235 /* Init the handle member. */
236 handle->transfer = *xfer;
237
238 /* Save total transfer size. */
239 handle->transferSize = xfer->dataSize;
240
241 handle->state = kTransferDataState;
242
243 /* Clear all status before transfer. */
244 I2C_MasterClearStatusFlags(base, kClearFlags);
245
246 /* Change to send write address when it's a read operation with command. */
247 if ((xfer->subaddressSize > 0) && (xfer->direction == kI2C_Read))
248 {
249 direction = kI2C_Write;
250 }
251
252 /* If repeated start is requested, send repeated start. */
253 if (handle->transfer.flags & kI2C_TransferRepeatedStartFlag)
254 {
255 result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, direction);
256 }
257 else /* For normal transfer, send start. */
258 {
259 result = I2C_MasterStart(base, handle->transfer.slaveAddress, direction);
260 }
261
262 if (result)
263 {
264 return result;
265 }
266
267 while (!(base->S & kI2C_IntPendingFlag))
268 {
269 }
270
271 /* Check if there's transfer error. */
272 result = I2C_CheckAndClearError(base, base->S);
273
274 /* Return if error. */
275 if (result)
276 {
277 if (result == kStatus_I2C_Nak)
278 {
279 result = kStatus_I2C_Addr_Nak;
280
281 if (I2C_MasterStop(base) != kStatus_Success)
282 {
283 result = kStatus_I2C_Timeout;
284 }
285
286 if (handle->completionCallback)
287 {
288 (handle->completionCallback)(base, handle, result, handle->userData);
289 }
290 }
291
292 return result;
293 }
294
295 /* Send subaddress. */
296 if (handle->transfer.subaddressSize)
297 {
298 do
299 {
300 /* Clear interrupt pending flag. */
301 base->S = kI2C_IntPendingFlag;
302
303 handle->transfer.subaddressSize--;
304 base->D = ((handle->transfer.subaddress) >> (8 * handle->transfer.subaddressSize));
305
306 /* Wait until data transfer complete. */
307 while (!(base->S & kI2C_IntPendingFlag))
308 {
309 }
310
311 /* Check if there's transfer error. */
312 result = I2C_CheckAndClearError(base, base->S);
313
314 if (result)
315 {
316 return result;
317 }
318
319 } while ((handle->transfer.subaddressSize > 0) && (result == kStatus_Success));
320
321 if (handle->transfer.direction == kI2C_Read)
322 {
323 /* Clear pending flag. */
324 base->S = kI2C_IntPendingFlag;
325
326 /* Send repeated start and slave address. */
327 result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, kI2C_Read);
328
329 if (result)
330 {
331 return result;
332 }
333
334 /* Wait until data transfer complete. */
335 while (!(base->S & kI2C_IntPendingFlag))
336 {
337 }
338
339 /* Check if there's transfer error. */
340 result = I2C_CheckAndClearError(base, base->S);
341
342 if (result)
343 {
344 return result;
345 }
346 }
347 }
348
349 /* Clear pending flag. */
350 base->S = kI2C_IntPendingFlag;
351 }
352
353 return result;
354 }
355
I2C_MasterTransferEDMAConfig(I2C_Type * base,i2c_master_edma_handle_t * handle)356 static void I2C_MasterTransferEDMAConfig(I2C_Type *base, i2c_master_edma_handle_t *handle)
357 {
358 edma_transfer_config_t transfer_config;
359
360 if (handle->transfer.direction == kI2C_Read)
361 {
362 transfer_config.srcAddr = (uint32_t)I2C_GetDataRegAddr(base);
363 transfer_config.destAddr = (uint32_t)(handle->transfer.data);
364 transfer_config.majorLoopCounts = (handle->transfer.dataSize - 1);
365 transfer_config.srcTransferSize = kEDMA_TransferSize1Bytes;
366 transfer_config.srcOffset = 0;
367 transfer_config.destTransferSize = kEDMA_TransferSize1Bytes;
368 transfer_config.destOffset = 1;
369 transfer_config.minorLoopBytes = 1;
370 }
371 else
372 {
373 transfer_config.srcAddr = (uint32_t)(handle->transfer.data + 1);
374 transfer_config.destAddr = (uint32_t)I2C_GetDataRegAddr(base);
375 transfer_config.majorLoopCounts = (handle->transfer.dataSize - 1);
376 transfer_config.srcTransferSize = kEDMA_TransferSize1Bytes;
377 transfer_config.srcOffset = 1;
378 transfer_config.destTransferSize = kEDMA_TransferSize1Bytes;
379 transfer_config.destOffset = 0;
380 transfer_config.minorLoopBytes = 1;
381 }
382
383 /* Store the initially configured eDMA minor byte transfer count into the I2C handle */
384 handle->nbytes = transfer_config.minorLoopBytes;
385
386 EDMA_SubmitTransfer(handle->dmaHandle, &transfer_config);
387 EDMA_StartTransfer(handle->dmaHandle);
388 }
389
I2C_MasterCreateEDMAHandle(I2C_Type * base,i2c_master_edma_handle_t * handle,i2c_master_edma_transfer_callback_t callback,void * userData,edma_handle_t * edmaHandle)390 void I2C_MasterCreateEDMAHandle(I2C_Type *base,
391 i2c_master_edma_handle_t *handle,
392 i2c_master_edma_transfer_callback_t callback,
393 void *userData,
394 edma_handle_t *edmaHandle)
395 {
396 assert(handle);
397 assert(edmaHandle);
398
399 uint32_t instance = I2C_GetInstance(base);
400
401 /* Zero handle. */
402 memset(handle, 0, sizeof(*handle));
403
404 /* Set the user callback and userData. */
405 handle->completionCallback = callback;
406 handle->userData = userData;
407
408 /* Set the base for the handle. */
409 base = base;
410
411 /* Set the handle for EDMA. */
412 handle->dmaHandle = edmaHandle;
413
414 s_edmaPrivateHandle[instance].base = base;
415 s_edmaPrivateHandle[instance].handle = handle;
416
417 EDMA_SetCallback(edmaHandle, (edma_callback)I2C_MasterTransferCallbackEDMA, &s_edmaPrivateHandle[instance]);
418 }
419
I2C_MasterTransferEDMA(I2C_Type * base,i2c_master_edma_handle_t * handle,i2c_master_transfer_t * xfer)420 status_t I2C_MasterTransferEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle, i2c_master_transfer_t *xfer)
421 {
422 assert(handle);
423 assert(xfer);
424
425 status_t result;
426 uint8_t tmpReg;
427 volatile uint8_t dummy = 0;
428
429 /* Add this to avoid build warning. */
430 dummy++;
431
432 /* Disable dma xfer. */
433 I2C_EnableDMA(base, false);
434
435 /* Send address and command buffer(if there is), until senddata phase or receive data phase. */
436 result = I2C_InitTransferStateMachineEDMA(base, handle, xfer);
437
438 if (result)
439 {
440 /* Send stop if received Nak. */
441 if (result == kStatus_I2C_Nak)
442 {
443 if (I2C_MasterStop(base) != kStatus_Success)
444 {
445 result = kStatus_I2C_Timeout;
446 }
447 }
448
449 /* Reset the state to idle state. */
450 handle->state = kIdleState;
451
452 return result;
453 }
454
455 /* Configure dma transfer. */
456 /* For i2c send, need to send 1 byte first to trigger the dma, for i2c read,
457 need to send stop before reading the last byte, so the dma transfer size should
458 be (xSize - 1). */
459 if (handle->transfer.dataSize > 1)
460 {
461 I2C_MasterTransferEDMAConfig(base, handle);
462 if (handle->transfer.direction == kI2C_Read)
463 {
464 /* Change direction for receive. */
465 base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
466
467 /* Read dummy to release the bus. */
468 dummy = base->D;
469
470 /* Enabe dma transfer. */
471 I2C_EnableDMA(base, true);
472 }
473 else
474 {
475 /* Enabe dma transfer. */
476 I2C_EnableDMA(base, true);
477
478 /* Send the first data. */
479 base->D = *handle->transfer.data;
480 }
481 }
482 else /* If transfer size is 1, use polling method. */
483 {
484 if (handle->transfer.direction == kI2C_Read)
485 {
486 tmpReg = base->C1;
487
488 /* Change direction to Rx. */
489 tmpReg &= ~I2C_C1_TX_MASK;
490
491 /* Configure send NAK */
492 tmpReg |= I2C_C1_TXAK_MASK;
493
494 base->C1 = tmpReg;
495
496 /* Read dummy to release the bus. */
497 dummy = base->D;
498 }
499 else
500 {
501 base->D = *handle->transfer.data;
502 }
503
504 /* Wait until data transfer complete. */
505 while (!(base->S & kI2C_IntPendingFlag))
506 {
507 }
508
509 /* Clear pending flag. */
510 base->S = kI2C_IntPendingFlag;
511
512 /* Send stop if kI2C_TransferNoStop flag is not asserted. */
513 if (!(handle->transfer.flags & kI2C_TransferNoStopFlag))
514 {
515 result = I2C_MasterStop(base);
516 }
517 else
518 {
519 /* Change direction to send. */
520 base->C1 |= I2C_C1_TX_MASK;
521 }
522
523 /* Read the last byte of data. */
524 if (handle->transfer.direction == kI2C_Read)
525 {
526 *handle->transfer.data = base->D;
527 }
528
529 /* Reset the state to idle. */
530 handle->state = kIdleState;
531 }
532
533 return result;
534 }
535
I2C_MasterTransferGetCountEDMA(I2C_Type * base,i2c_master_edma_handle_t * handle,size_t * count)536 status_t I2C_MasterTransferGetCountEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle, size_t *count)
537 {
538 assert(handle->dmaHandle);
539
540 if (!count)
541 {
542 return kStatus_InvalidArgument;
543 }
544
545 if (kIdleState != handle->state)
546 {
547 *count = (handle->transferSize -
548 (uint32_t)handle->nbytes *
549 EDMA_GetRemainingMajorLoopCount(handle->dmaHandle->base, handle->dmaHandle->channel));
550 }
551 else
552 {
553 *count = handle->transferSize;
554 }
555
556 return kStatus_Success;
557 }
558
I2C_MasterTransferAbortEDMA(I2C_Type * base,i2c_master_edma_handle_t * handle)559 void I2C_MasterTransferAbortEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle)
560 {
561 EDMA_AbortTransfer(handle->dmaHandle);
562
563 /* Disable dma transfer. */
564 I2C_EnableDMA(base, false);
565
566 /* Reset the state to idle. */
567 handle->state = kIdleState;
568 }
569