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