1 /*
2  * Copyright (c) 2015-2020, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #include <stdint.h>
34 #include <stdbool.h>
35 #include <stdlib.h>
36 
37 /*
38  * By default disable asserts for this module.
39  * This must be done before DebugP.h is included.
40  */
41 #ifndef DebugP_ASSERT_ENABLED
42 #define DebugP_ASSERT_ENABLED 0
43 #endif
44 
45 #include <ti/drivers/dpl/DebugP.h>
46 #include <ti/drivers/dpl/ClockP.h>
47 #include <ti/drivers/dpl/HwiP.h>
48 #include <ti/drivers/dpl/SemaphoreP.h>
49 
50 #include <ti/drivers/Power.h>
51 #include <ti/drivers/power/PowerCC32XX.h>
52 
53 #include <ti/drivers/i2c/I2CCC32XX.h>
54 
55 #include <ti/devices/cc32xx/inc/hw_types.h>
56 #include <ti/devices/cc32xx/inc/hw_memmap.h>
57 #include <ti/devices/cc32xx/inc/hw_common_reg.h>
58 #include <ti/devices/cc32xx/inc/hw_ocp_shared.h>
59 #include <ti/devices/cc32xx/driverlib/rom.h>
60 #include <ti/devices/cc32xx/driverlib/rom_map.h>
61 #include <ti/devices/cc32xx/driverlib/i2c.h>
62 #include <ti/devices/cc32xx/driverlib/prcm.h>
63 #include <ti/devices/cc32xx/inc/hw_i2c.h>
64 #include <ti/devices/cc32xx/driverlib/pin.h>
65 
66 /* Pad configuration defines */
67 #define PAD_CONFIG_BASE (OCP_SHARED_BASE + OCP_SHARED_O_GPIO_PAD_CONFIG_0)
68 #define PAD_DEFAULT_STATE 0xC60 /* pad reset, plus set GPIO mode to free I2C */
69 
70 #define I2CCC32XX_ERROR_INTS (I2C_MASTER_INT_NACK | \
71     I2C_MASTER_INT_ARB_LOST | I2C_MASTER_INT_TIMEOUT)
72 
73 #define I2CCC32XX_TRANSFER_INTS (I2C_MASTER_INT_STOP | \
74         I2CCC32XX_ERROR_INTS)
75 
76 #define I2CCC32XX_FIFO_SIZE 8
77 #define I2CCC32XX_MAX_BURST 255
78 
79 /* Map MCS read bits to write bits */
80 #define I2C_MCS_START (I2C_MCS_ERROR)
81 #define I2C_MCS_STOP (I2C_MCS_ADRACK)
82 #define I2C_MCS_BURST (I2C_MCS_BUSBSY)
83 #define I2C_MCS_DATACK (I2C_MCS_ACK)
84 
85 /* Prototypes */
86 void I2CCC32XX_cancel(I2C_Handle handle);
87 void I2CCC32XX_close(I2C_Handle handle);
88 int_fast16_t I2CCC32XX_control(I2C_Handle handle, uint_fast16_t cmd, void *arg);
89 void I2CCC32XX_init(I2C_Handle handle);
90 I2C_Handle I2CCC32XX_open(I2C_Handle handle, I2C_Params *params);
91 void I2CCC32XX_reset();
92 int_fast16_t I2CCC32XX_transfer(I2C_Handle handle,
93     I2C_Transaction *transaction, uint32_t timeout);
94 
95 static void I2CCC32XX_blockingCallback(I2C_Handle handle, I2C_Transaction *msg,
96     bool transferStatus);
97 static void I2CCC32XX_completeTransfer(I2C_Handle handle);
98 static void I2CCC32XX_initHw(I2C_Handle handle);
99 static int I2CCC32XX_postNotify(unsigned int eventType, uintptr_t eventArg,
100     uintptr_t clientArg);
101 static void I2CCC32XX_primeReadBurst(I2CCC32XX_Object *object,
102     I2CCC32XX_HWAttrsV1 const *hwAttrs);
103 static void I2CCC32XX_primeWriteBurst(I2CCC32XX_Object *object,
104     I2CCC32XX_HWAttrsV1 const *hwAttrs);
105 static int_fast16_t I2CCC32XX_primeTransfer(I2CCC32XX_Object *object,
106     I2CCC32XX_HWAttrsV1 const *hwAttrs, I2C_Transaction *transaction);
107 static void I2CCC32XX_readRecieveFifo(I2CCC32XX_Object *object,
108     I2CCC32XX_HWAttrsV1 const *hwAttrs);
109 static void I2CCC32XX_updateReg(uint32_t reg, uint32_t mask, uint32_t val);
110 
111 /* I2C function table for I2CCC32XX implementation */
112 const I2C_FxnTable I2CCC32XX_fxnTable = {
113     I2CCC32XX_cancel,
114     I2CCC32XX_close,
115     I2CCC32XX_control,
116     I2CCC32XX_init,
117     I2CCC32XX_open,
118     I2CCC32XX_transfer
119 };
120 
121 /*
122  *  ======== I2CCC32XX_blockingCallback ========
123  */
I2CCC32XX_blockingCallback(I2C_Handle handle,I2C_Transaction * msg,bool transferStatus)124 static void I2CCC32XX_blockingCallback(I2C_Handle handle,
125     I2C_Transaction *msg, bool transferStatus)
126 {
127     I2CCC32XX_Object  *object = handle->object;
128 
129     /* Indicate transfer complete */
130     SemaphoreP_post(object->transferComplete);
131 }
132 
133 /*
134  *  ======== I2CCC32XX_fillTransmitFifo ========
135  */
I2CCC32XX_fillTransmitFifo(I2CCC32XX_Object * object,I2CCC32XX_HWAttrsV1 const * hwAttrs)136 static inline void I2CCC32XX_fillTransmitFifo(I2CCC32XX_Object *object,
137     I2CCC32XX_HWAttrsV1 const *hwAttrs)
138 {
139     while(object->writeCount && object->burstCount &&
140         I2CFIFODataPutNonBlocking(hwAttrs->baseAddr, *(object->writeBuf))) {
141 
142         object->writeBuf++;
143         object->writeCount--;
144         object->burstCount--;
145     }
146 
147     I2CMasterIntClearEx(hwAttrs->baseAddr, I2C_MASTER_INT_TX_FIFO_EMPTY);
148 }
149 
150 /*
151  *  ======== I2CCC32XX_initHw ========
152  */
I2CCC32XX_initHw(I2C_Handle handle)153 static void I2CCC32XX_initHw(I2C_Handle handle)
154 {
155     ClockP_FreqHz              freq;
156     I2CCC32XX_Object          *object = handle->object;
157     I2CCC32XX_HWAttrsV1 const *hwAttrs = handle->hwAttrs;
158     uint32_t                   ulRegVal;
159 
160     /*
161      *  Take I2C hardware semaphore to prevent NWP from accessing I2C.
162      *
163      *  This is done in initHw() instead of postNotify(), so the
164      *  hardware sempahore is also taken during open().
165      */
166     ulRegVal = HWREG(COMMON_REG_BASE + COMMON_REG_O_I2C_Properties_Register);
167     ulRegVal = (ulRegVal & ~0x3) | 0x1;
168     HWREG(0x400F7000) = ulRegVal;
169 
170     /* Disable all interrupts */
171     MAP_I2CMasterIntDisableEx(hwAttrs->baseAddr, 0xFFFFFFFF);
172 
173     /* Get CPU Frequency */
174     ClockP_getCpuFreq(&freq);
175 
176     /* I2CMasterEnable() invoked in this call */
177     MAP_I2CMasterInitExpClk(hwAttrs->baseAddr, freq.lo,
178         object->bitRate > I2C_100kHz);
179 
180     /* Flush the FIFOs. They must be empty before re-assignment */
181     MAP_I2CTxFIFOFlush(hwAttrs->baseAddr);
182     MAP_I2CRxFIFOFlush(hwAttrs->baseAddr);
183 
184     /* Set TX and RX FIFOs to master mode */
185     MAP_I2CTxFIFOConfigSet(hwAttrs->baseAddr, I2C_FIFO_CFG_TX_MASTER);
186     MAP_I2CRxFIFOConfigSet(hwAttrs->baseAddr, I2C_FIFO_CFG_RX_MASTER);
187 
188     /* Clear any pending interrupts */
189     MAP_I2CMasterIntClearEx(hwAttrs->baseAddr, 0xFFFFFFFF);
190 }
191 
192 /*
193  *  ======== I2CCC32XX_postNotify ========
194  *  This functions is called to notify the I2C driver of an ongoing transition
195  *  out of LPDS mode.
196  *  clientArg should be pointing to a hardware module which has already
197  *  been opened.
198  */
I2CCC32XX_postNotify(unsigned int eventType,uintptr_t eventArg,uintptr_t clientArg)199 static int I2CCC32XX_postNotify(unsigned int eventType,
200     uintptr_t eventArg, uintptr_t clientArg)
201 {
202     /* Reconfigure the hardware when returning from LPDS */
203     I2CCC32XX_initHw((I2C_Handle) clientArg);
204 
205     return (Power_NOTIFYDONE);
206 }
207 
208 
209 /*
210  *  ======== I2CCC32XX_completeTransfer ========
211  */
I2CCC32XX_completeTransfer(I2C_Handle handle)212 static void I2CCC32XX_completeTransfer(I2C_Handle handle)
213 {
214     I2CCC32XX_Object *object = handle->object;
215     I2CCC32XX_HWAttrsV1 const *hwAttrs = handle->hwAttrs;
216 
217     /* Disable and clear all interrupts */
218     I2CMasterIntDisableEx(hwAttrs->baseAddr, 0xFFFFFFFF);
219     I2CMasterIntClearEx(hwAttrs->baseAddr, 0xFFFFFFFF);
220 
221     /*
222      *  If this current transaction was canceled, we need to cancel
223      *  any queued transactions
224      */
225     if (object->currentTransaction->status == I2C_STATUS_CANCEL) {
226 
227         /*
228          * Allow callback to run. If in CALLBACK mode, the application
229          * may initiate a transfer in the callback which will call
230          * primeTransfer().
231          */
232         object->transferCallbackFxn(handle, object->currentTransaction, false);
233         object->currentTransaction->status = I2C_STATUS_CANCEL;
234 
235         /* also dequeue and call the transfer callbacks for any queued transfers */
236         while (object->headPtr != object->tailPtr) {
237             object->headPtr = object->headPtr->nextPtr;
238             object->headPtr->status = I2C_STATUS_CANCEL;
239             object->transferCallbackFxn(handle, object->headPtr, false);
240             object->headPtr->status = I2C_STATUS_CANCEL;
241         }
242 
243         /* clean up object */
244         object->currentTransaction = NULL;
245         object->headPtr = NULL;
246         object->tailPtr = NULL;
247     }
248     /* See if we need to process any other transactions */
249     else if (object->headPtr == object->tailPtr) {
250 
251         /* No other transactions need to occur */
252         object->headPtr = NULL;
253         object->tailPtr = NULL;
254 
255         /*
256          * Allow callback to run. If in CALLBACK mode, the application
257          * may initiate a transfer in the callback which will call
258          * primeTransfer().
259          */
260         object->transferCallbackFxn(handle, object->currentTransaction,
261             (object->currentTransaction->status == I2C_STATUS_SUCCESS));
262 
263         /* Release constraint since transaction is done */
264         Power_releaseConstraint(PowerCC32XX_DISALLOW_LPDS);
265     }
266     else {
267         /* Another transfer needs to take place */
268         object->headPtr = object->headPtr->nextPtr;
269 
270         /*
271          * Allow application callback to run. The application may
272          * initiate a transfer in the callback which will add an
273          * additional transfer to the queue.
274          */
275         object->transferCallbackFxn(handle, object->currentTransaction,
276             (object->currentTransaction->status == I2C_STATUS_SUCCESS));
277 
278         I2CCC32XX_primeTransfer(object,
279             (I2CCC32XX_HWAttrsV1 const *)handle->hwAttrs, object->headPtr);
280     }
281 }
282 
283 /*
284  *  ======== I2CCC32XX_control ========
285  *  @pre    Function assumes that the handle is not NULL
286  */
I2CCC32XX_control(I2C_Handle handle,uint_fast16_t cmd,void * arg)287 int_fast16_t I2CCC32XX_control(I2C_Handle handle, uint_fast16_t cmd, void *arg)
288 {
289     /* No implementation yet */
290     return (I2C_STATUS_UNDEFINEDCMD);
291 }
292 
293 /*
294  *  ======== I2CCC32XX_hwiFxn ========
295  *  Hwi interrupt handler to service the I2C peripheral
296  *
297  *  The handler is a generic handler for a I2C object.
298  */
I2CCC32XX_hwiFxn(uintptr_t arg)299 static void I2CCC32XX_hwiFxn(uintptr_t arg)
300 {
301     /* Get the pointer to the object and hwAttrs */
302     I2CCC32XX_Object *object = ((I2C_Handle)arg)->object;
303     I2CCC32XX_HWAttrsV1 const *hwAttrs = ((I2C_Handle)arg)->hwAttrs;
304     uint32_t intStatus;
305 
306     /* Read and clear masked interrupts */
307     intStatus = I2CMasterIntStatusEx(hwAttrs->baseAddr, true);
308     I2CMasterIntClearEx(hwAttrs->baseAddr, intStatus);
309 
310     if (intStatus & I2CCC32XX_ERROR_INTS) {
311 
312         /* The MSR contains all error bits */
313         uint32_t status = HWREG(hwAttrs->baseAddr + I2C_O_MCS);
314 
315         /* Decode interrupt status */
316         if (status & I2C_MCS_ARBLST) {
317             object->currentTransaction->status = I2C_STATUS_ARB_LOST;
318         }
319         else if (status & I2C_MCS_DATACK) {
320             object->currentTransaction->status = I2C_STATUS_DATA_NACK;
321         }
322         else if (status & I2C_MCS_ADRACK) {
323             object->currentTransaction->status = I2C_STATUS_ADDR_NACK;
324         }
325         else if (status & I2C_MCS_CLKTO) {
326             object->currentTransaction->status = I2C_STATUS_CLOCK_TIMEOUT;
327         }
328         else {
329             object->currentTransaction->status = I2C_STATUS_ERROR;
330         }
331 
332         /* If arbitration is lost, another I2C master owns the bus */
333         if (status & I2C_MCS_ARBLST) {
334             I2CCC32XX_completeTransfer((I2C_Handle) arg);
335             return;
336         }
337 
338         /* If the stop interrupt has not occurred, force a STOP condition */
339         if (!(intStatus & I2C_MASTER_INT_STOP)) {
340 
341             HWREG(hwAttrs->baseAddr + I2C_O_MCS) = I2C_MCS_STOP;
342             return;
343         }
344     }
345     else if (intStatus & I2C_MASTER_INT_TX_FIFO_EMPTY) {
346 
347         /* If there is more data to transmit */
348         if (object->writeCount) {
349 
350             /* If we need to configure a new burst */
351             if (0 == object->burstCount) {
352                 I2CCC32XX_primeWriteBurst(object, hwAttrs);
353             }
354             else {
355                 I2CCC32XX_fillTransmitFifo(object, hwAttrs);
356             }
357         }
358         /* Finished writing, is there data to receive? */
359         else if (object->readCount) {
360 
361             /* Disable TX interrupt */
362             I2CMasterIntDisableEx(hwAttrs->baseAddr,
363                 I2C_MASTER_INT_TX_FIFO_EMPTY);
364 
365             object->burstStarted = false;
366             I2CCC32XX_primeReadBurst(object, hwAttrs);
367         }
368     }
369     else if (intStatus & I2C_MASTER_INT_RX_FIFO_REQ ||
370        !(HWREG(hwAttrs->baseAddr + I2C_O_FIFOSTATUS) & I2C_FIFOSTATUS_RXFE)) {
371 
372         I2CCC32XX_readRecieveFifo(object, hwAttrs);
373 
374         /* If we need to configure a new burst */
375         if (object->readCount && (0 == object->burstCount)) {
376             I2CCC32XX_primeReadBurst(object, hwAttrs);
377         }
378     }
379 
380     /* If the STOP condition was set, complete the transfer */
381     if (intStatus & I2C_MASTER_INT_STOP) {
382 
383         /* If the transaction completed, update the transaction status */
384         if (object->currentTransaction->status == I2C_STATUS_INCOMPLETE &&
385             (!(object->readCount || object->writeCount))) {
386 
387             uint32_t fifoStatus = I2CFIFOStatus(hwAttrs->baseAddr) &
388                 (I2C_FIFO_TX_EMPTY | I2C_FIFO_RX_EMPTY);
389 
390             /* If both FIFOs are empty */
391             if (fifoStatus == (I2C_FIFO_RX_EMPTY | I2C_FIFO_TX_EMPTY)) {
392                 object->currentTransaction->status = I2C_STATUS_SUCCESS;
393             }
394         }
395 
396         I2CCC32XX_completeTransfer((I2C_Handle) arg);
397     }
398 }
399 
400 
401 /*
402  *  ======== I2CCC32XX_primeReadBurst =======
403  */
I2CCC32XX_primeReadBurst(I2CCC32XX_Object * object,I2CCC32XX_HWAttrsV1 const * hwAttrs)404 static void I2CCC32XX_primeReadBurst(I2CCC32XX_Object *object,
405     I2CCC32XX_HWAttrsV1 const *hwAttrs)
406 {
407     uint32_t command;
408 
409     /* Specify the I2C slave address in receive mode */
410     I2CMasterSlaveAddrSet(hwAttrs->baseAddr,
411         object->currentTransaction->slaveAddress, true);
412 
413     /* Determine the size of this burst */
414     if(object->readCount > I2CCC32XX_MAX_BURST) {
415         object->burstCount = I2CCC32XX_MAX_BURST;
416     }
417     else {
418         object->burstCount = object->readCount;
419     }
420 
421     /*
422      * If we are reading less than FIFO_SIZE bytes, set the RX FIFO
423      * REQ interrupt to trigger when we finish burstCount bytes.
424      * Else we are reading more than 8 bytes. set the RX FIFO REQ
425      * interrupt to trigger when full. If we are reading less than RXTRIG
426      * bytes during the final byte reads, the RXDONE interrupt will allow
427      * us to complete the read transaction.
428      */
429     if(object->burstCount < I2CCC32XX_FIFO_SIZE) {
430         I2CCC32XX_updateReg(hwAttrs->baseAddr + I2C_O_FIFOCTL,
431             I2C_FIFOCTL_RXTRIG_M, object->burstCount << I2C_FIFOCTL_RXTRIG_S);
432     }
433     else {
434         I2CCC32XX_updateReg(hwAttrs->baseAddr + I2C_O_FIFOCTL,
435             I2C_FIFOCTL_RXTRIG_M, I2C_FIFOCTL_RXTRIG_M);
436     }
437 
438     I2CMasterBurstLengthSet(hwAttrs->baseAddr, object->burstCount);
439 
440     /* If we will be sending multiple bursts */
441     if(object->readCount > I2CCC32XX_MAX_BURST) {
442          /* Setting the ACK enable ensures we ACK the last byte of a burst */
443          command = (I2C_MCS_BURST | I2C_MCS_ACK);
444     }
445     else {
446          command = (I2C_MCS_BURST | I2C_MCS_STOP);
447     }
448 
449     /* Only generate a start condition if the burst hasn't started */
450     if (!object->burstStarted) {
451         command |= I2C_MCS_START;
452         object->burstStarted = true;
453     }
454 
455     I2CMasterIntEnableEx(hwAttrs->baseAddr, I2C_MASTER_INT_RX_FIFO_REQ |
456         I2CCC32XX_TRANSFER_INTS);
457 
458     HWREG(hwAttrs->baseAddr + I2C_O_MCS) = command;
459 }
460 
461 /*
462  *  ======== I2CCC32XX_primeWriteBurst =======
463  */
I2CCC32XX_primeWriteBurst(I2CCC32XX_Object * object,I2CCC32XX_HWAttrsV1 const * hwAttrs)464 static void I2CCC32XX_primeWriteBurst(I2CCC32XX_Object  *object,
465     I2CCC32XX_HWAttrsV1 const *hwAttrs)
466 {
467     uint32_t command;
468 
469     /* Write I2C Slave Address and transmit direction */
470     I2CMasterSlaveAddrSet(hwAttrs->baseAddr,
471         object->currentTransaction->slaveAddress, false);
472 
473     /* Determine the size of this burst */
474     if(object->writeCount > I2CCC32XX_MAX_BURST) {
475         object->burstCount = I2CCC32XX_MAX_BURST;
476     }
477     else {
478         object->burstCount = object->writeCount;
479     }
480 
481     /* Write burst length */
482     I2CMasterBurstLengthSet(hwAttrs->baseAddr,
483         object->burstCount);
484 
485     /* If we will be sending multiple bursts */
486     if (object->readCount || object->writeCount > I2CCC32XX_MAX_BURST) {
487         command = I2C_MCS_BURST;
488     }
489     else {
490         command = I2C_MCS_BURST | I2C_MCS_STOP;
491     }
492 
493     /* Only generate a start condition if the burst hasn't started */
494     if (!object->burstStarted) {
495         command |= I2C_MCS_START;
496         object->burstStarted = true;
497     }
498 
499     /* Fill transmit FIFO. This will modify the object counts */
500     I2CCC32XX_fillTransmitFifo(object, hwAttrs);
501 
502     /* Enable TXFIFOEMPTY interrupt and other standard transfer interrupts */
503     I2CMasterIntEnableEx(hwAttrs->baseAddr, I2C_MASTER_INT_TX_FIFO_EMPTY
504         | I2CCC32XX_TRANSFER_INTS);
505 
506     /* Write the Master Control & Status register */
507     HWREG(hwAttrs->baseAddr + I2C_O_MCS) = command;
508 }
509 
510 /*
511  *  ======== I2CCC32XX_primeTransfer =======
512  */
I2CCC32XX_primeTransfer(I2CCC32XX_Object * object,I2CCC32XX_HWAttrsV1 const * hwAttrs,I2C_Transaction * transaction)513 static int_fast16_t I2CCC32XX_primeTransfer(I2CCC32XX_Object *object,
514     I2CCC32XX_HWAttrsV1 const *hwAttrs, I2C_Transaction *transaction)
515 {
516     int_fast16_t status = I2C_STATUS_SUCCESS;
517 
518     /* Store the new internal counters and pointers */
519     object->currentTransaction = transaction;
520 
521     object->writeBuf = transaction->writeBuf;
522     object->writeCount = transaction->writeCount;
523 
524     object->readBuf = transaction->readBuf;
525     object->readCount = transaction->readCount;
526 
527     object->burstCount = 0;
528     object->burstStarted = false;
529 
530     /*
531      * Transaction is incomplete unless the stop condition occurs AND
532      * all bytes have been sent and received. This condition is checked
533      * in the hardware interrupt when the STOP condition occurs.
534      */
535     transaction->status = I2C_STATUS_INCOMPLETE;
536 
537     /* Flush the FIFOs */
538     I2CTxFIFOFlush(hwAttrs->baseAddr);
539     I2CRxFIFOFlush(hwAttrs->baseAddr);
540 
541     /* Determine if the bus is in use by another I2C Master */
542     if (I2CMasterBusBusy(hwAttrs->baseAddr))
543     {
544         transaction->status = I2C_STATUS_BUS_BUSY;
545         status = I2C_STATUS_BUS_BUSY;
546     }
547     /* Start transfer in Transmit mode */
548     else if (object->writeCount) {
549         I2CCC32XX_primeWriteBurst(object, hwAttrs);
550     }
551     /* Start transfer in Receive mode */
552     else {
553         I2CCC32XX_primeReadBurst(object, hwAttrs);
554     }
555 
556     return (status);
557 }
558 
559 /*
560  *  ======== I2CCC32XX_readRecieveFifo ========
561  */
I2CCC32XX_readRecieveFifo(I2CCC32XX_Object * object,I2CCC32XX_HWAttrsV1 const * hwAttrs)562 static void I2CCC32XX_readRecieveFifo(I2CCC32XX_Object *object,
563     I2CCC32XX_HWAttrsV1 const *hwAttrs)
564 {
565 
566     while(object->readCount && object->burstCount &&
567         I2CFIFODataGetNonBlocking(hwAttrs->baseAddr, object->readBuf)) {
568         object->readBuf++;
569         object->readCount--;
570         object->burstCount--;
571     }
572 
573     I2CMasterIntClearEx(hwAttrs->baseAddr, I2C_MASTER_INT_RX_FIFO_REQ);
574 }
575 
576 /*
577  *  ======== I2CCC32XX_updateReg ========
578  */
I2CCC32XX_updateReg(uint32_t reg,uint32_t mask,uint32_t val)579 static void I2CCC32XX_updateReg(uint32_t reg, uint32_t mask, uint32_t val)
580 {
581     uint32_t regL = HWREG(reg) & ~mask;
582     HWREG(reg) = (regL | (val & mask));
583 }
584 
585 /*
586  *  ======== I2CC32XX_cancel ========
587  */
I2CCC32XX_cancel(I2C_Handle handle)588 void I2CCC32XX_cancel(I2C_Handle handle)
589 {
590     I2CCC32XX_Object          *object = handle->object;
591     I2CCC32XX_HWAttrsV1 const *hwAttrs = handle->hwAttrs;
592     uintptr_t key;
593 
594     key = HwiP_disable();
595 
596     /* Return if no transfer in progress */
597     if (!object->headPtr) {
598         HwiP_restore(key);
599         return;
600     }
601 
602     /*
603      * Writing the STOP command may put the I2C peripheral's FSM in a
604      * bad state, so we write RUN | STOP such that the current burst
605      * is transferred or received.
606      */
607     MAP_I2CMasterControl(hwAttrs->baseAddr, I2C_MASTER_CMD_BURST_SEND_FINISH);
608 
609     /* Set current transaction as canceled */
610     object->currentTransaction->status = I2C_STATUS_CANCEL;
611 
612     HwiP_restore(key);
613 }
614 
615 /*
616  *  ======== I2CCC32XX_close ========
617  */
I2CCC32XX_close(I2C_Handle handle)618 void I2CCC32XX_close(I2C_Handle handle)
619 {
620     I2CCC32XX_Object          *object = handle->object;
621     I2CCC32XX_HWAttrsV1 const *hwAttrs = handle->hwAttrs;
622     uint32_t                  padRegister;
623 
624     /* Check to see if a I2C transaction is in progress */
625     DebugP_assert(object->headPtr == NULL);
626 
627     /* Mask I2C interrupts */
628     MAP_I2CMasterIntDisableEx(hwAttrs->baseAddr, I2CCC32XX_TRANSFER_INTS);
629 
630     /* Disable the I2C Master */
631     MAP_I2CMasterDisable(hwAttrs->baseAddr);
632 
633     /* Disable I2C module clocks */
634     Power_releaseDependency(PowerCC32XX_PERIPH_I2CA0);
635 
636     Power_unregisterNotify(&(object->notifyObj));
637 
638     /* Restore pin pads to their reset states */
639     padRegister = (PinToPadGet((hwAttrs->clkPin) & 0xff)<<2) + PAD_CONFIG_BASE;
640     HWREG(padRegister) = PAD_DEFAULT_STATE;
641     padRegister = (PinToPadGet((hwAttrs->dataPin) & 0xff)<<2) + PAD_CONFIG_BASE;
642     HWREG(padRegister) = PAD_DEFAULT_STATE;
643 
644     if (object->hwiHandle) {
645         HwiP_delete(object->hwiHandle);
646         object->hwiHandle = NULL;
647     }
648     if (object->mutex) {
649         SemaphoreP_delete(object->mutex);
650         object->mutex = NULL;
651     }
652     /* Destruct the Semaphore */
653     if (object->transferComplete) {
654         SemaphoreP_delete(object->transferComplete);
655         object->transferComplete = NULL;
656     }
657 
658     object->isOpen = false;
659 
660     return;
661 }
662 
663 /*
664  *  ======== I2CCC32XX_init ========
665  */
I2CCC32XX_init(I2C_Handle handle)666 void I2CCC32XX_init(I2C_Handle handle)
667 {
668 }
669 
670 /*
671  *  ======== I2CCC32XX_open ========
672  */
I2CCC32XX_open(I2C_Handle handle,I2C_Params * params)673 I2C_Handle I2CCC32XX_open(I2C_Handle handle, I2C_Params *params)
674 {
675     uintptr_t                  key;
676     I2CCC32XX_Object          *object = handle->object;
677     I2CCC32XX_HWAttrsV1 const *hwAttrs = handle->hwAttrs;
678     SemaphoreP_Params          semParams;
679     HwiP_Params                hwiParams;
680     uint16_t                   pin;
681     uint16_t                   mode;
682 
683     /* Check for valid bit rate */
684     if (params->bitRate > I2C_400kHz) {
685         return (NULL);
686     }
687 
688     /* Determine if the device index was already opened */
689     key = HwiP_disable();
690     if(object->isOpen == true){
691         HwiP_restore(key);
692         return (NULL);
693     }
694 
695     /* Mark the handle as being used */
696     object->isOpen = true;
697     HwiP_restore(key);
698 
699     /* Save parameters */
700     object->transferMode = params->transferMode;
701     object->transferCallbackFxn = params->transferCallbackFxn;
702     object->bitRate = params->bitRate;
703 
704     /* Enable the I2C module clocks */
705     Power_setDependency(PowerCC32XX_PERIPH_I2CA0);
706 
707     /* In case of app restart: disable I2C module, clear interrupt at NVIC */
708     MAP_I2CMasterDisable(hwAttrs->baseAddr);
709     HwiP_clearInterrupt(hwAttrs->intNum);
710 
711     pin = hwAttrs->clkPin & 0xff;
712     mode = (hwAttrs->clkPin >> 8) & 0xff;
713     MAP_PinTypeI2C((unsigned long)pin, (unsigned long)mode);
714 
715     pin = hwAttrs->dataPin & 0xff;
716     mode = (hwAttrs->dataPin >> 8) & 0xff;
717     MAP_PinTypeI2C((unsigned long)pin, (unsigned long)mode);
718 
719     Power_registerNotify(&(object->notifyObj), PowerCC32XX_AWAKE_LPDS,
720         I2CCC32XX_postNotify, (uint32_t)handle);
721 
722     HwiP_Params_init(&hwiParams);
723     hwiParams.arg = (uintptr_t)handle;
724     hwiParams.priority = hwAttrs->intPriority;
725     object->hwiHandle = HwiP_create(hwAttrs->intNum, I2CCC32XX_hwiFxn,
726         &hwiParams);
727     if (object->hwiHandle == NULL) {
728         I2CCC32XX_close(handle);
729         return (NULL);
730     }
731 
732     /*
733      * Create threadsafe handles for this I2C peripheral
734      * Semaphore to provide exclusive access to the I2C peripheral
735      */
736     SemaphoreP_Params_init(&semParams);
737     semParams.mode = SemaphoreP_Mode_BINARY;
738     object->mutex = SemaphoreP_create(1, &semParams);
739     if (object->mutex == NULL) {
740         I2CCC32XX_close(handle);
741         return (NULL);
742     }
743 
744     /*
745      * Store a callback function that posts the transfer complete
746      * semaphore for synchronous mode
747      */
748     if (object->transferMode == I2C_MODE_BLOCKING) {
749         /*
750          * Semaphore to cause the waiting task to block for the I2C
751          * to finish
752          */
753         object->transferComplete = SemaphoreP_create(0, &semParams);
754         if (object->transferComplete == NULL) {
755             I2CCC32XX_close(handle);
756             return (NULL);
757         }
758 
759         /* Store internal callback function */
760         object->transferCallbackFxn = I2CCC32XX_blockingCallback;
761     }
762     else {
763         /* Check to see if a callback function was defined for async mode */
764         DebugP_assert(object->transferCallbackFxn != NULL);
765     }
766 
767     /* Clear the head pointer */
768     object->headPtr = NULL;
769     object->tailPtr = NULL;
770     object->currentTransaction = NULL;
771 
772     /* Set the I2C configuration */
773     I2CCC32XX_initHw(handle);
774 
775     /* Return the address of the handle */
776     return (handle);
777 }
778 
779 
780 
781 
782 /*
783  *  ======== I2CC32XX_reset ========
784  */
I2CCC32XX_reset()785 void I2CCC32XX_reset()
786 {
787     PRCMPeripheralReset(PRCM_I2CA0);
788     while(!PRCMPeripheralStatusGet(PRCM_I2CA0)) {}
789 }
790 
791 /*
792  *  ======== I2CCC32XX_transfer ========
793  */
I2CCC32XX_transfer(I2C_Handle handle,I2C_Transaction * transaction,uint32_t timeout)794 int_fast16_t I2CCC32XX_transfer(I2C_Handle handle, I2C_Transaction *transaction,
795     uint32_t timeout)
796 {
797     uintptr_t key;
798     int_fast16_t ret;
799     I2CCC32XX_Object *object = handle->object;
800     I2CCC32XX_HWAttrsV1 const *hwAttrs = handle->hwAttrs;
801 
802     /* Check if anything needs to be written or read */
803     if ((!transaction->writeCount) && (!transaction->readCount)) {
804         transaction->status = I2C_STATUS_INVALID_TRANS;
805         /* Nothing to write or read */
806         return (transaction->status);
807     }
808 
809     key = HwiP_disable();
810 
811     if (object->transferMode == I2C_MODE_CALLBACK) {
812         /* Check if a transfer is in progress */
813         if (object->headPtr) {
814 
815             /*
816              * Queued transactions are being canceled. Can't allow additional
817              * transactions to be queued.
818              */
819             if (object->headPtr->status == I2C_STATUS_CANCEL) {
820                 transaction->status = I2C_STATUS_INVALID_TRANS;
821                 ret = transaction->status;
822             }
823             /* Transfer in progress */
824             else {
825 
826                 /*
827                  * Update the message pointed by the tailPtr to point to the next
828                  * message in the queue
829                  */
830                 object->tailPtr->nextPtr = transaction;
831 
832                 /* Update the tailPtr to point to the last message */
833                 object->tailPtr = transaction;
834 
835                 /* Set queued status */
836                 transaction->status = I2C_STATUS_QUEUED;
837 
838                 ret = I2C_STATUS_SUCCESS;
839             }
840 
841             HwiP_restore(key);
842             return (ret);
843         }
844     }
845 
846     /* Store the headPtr indicating I2C is in use */
847     object->headPtr = transaction;
848     object->tailPtr = transaction;
849 
850     /* In blocking mode, transactions can queue on the I2C mutex */
851     transaction->status = I2C_STATUS_QUEUED;
852 
853     HwiP_restore(key);
854 
855     /* Get the lock for this I2C handle */
856     if (SemaphoreP_pend(object->mutex, SemaphoreP_NO_WAIT)
857             == SemaphoreP_TIMEOUT) {
858 
859         /* We were unable to get the mutex in CALLBACK mode */
860         if (object->transferMode == I2C_MODE_CALLBACK) {
861             /*
862              * Recursively call transfer() and attempt to place transaction
863              * on the queue. This may only occur if a thread is preempted
864              * after restoring interrupts and attempting to grab this mutex.
865              */
866             return (I2CCC32XX_transfer(handle, transaction, timeout));
867         }
868 
869         /* Wait for the I2C lock. If it times-out before we retrieve it, then
870          * return I2C_STATUS_TIMEOUT to cancel the transaction. */
871         if(SemaphoreP_pend(object->mutex, timeout) == SemaphoreP_TIMEOUT) {
872             transaction->status = I2C_STATUS_TIMEOUT;
873             return (I2C_STATUS_TIMEOUT);
874         }
875     }
876 
877     if (object->transferMode == I2C_MODE_BLOCKING) {
878        /*
879         * In the case of a timeout, It is possible for the timed-out transaction
880         * to call the hwi function and post the object->transferComplete Semaphore
881         * To clear this, we simply do a NO_WAIT pend on (binary)
882         * object->transferComplete, so that it resets the Semaphore count.
883         */
884         SemaphoreP_pend(object->transferComplete, SemaphoreP_NO_WAIT);
885     }
886 
887     Power_setConstraint(PowerCC32XX_DISALLOW_LPDS);
888 
889     /*
890      * I2CCC32XX_primeTransfer is a longer process and
891      * protection is needed from the I2C interrupt
892      */
893     HwiP_disableInterrupt(hwAttrs->intNum);
894     ret = I2CCC32XX_primeTransfer(object, hwAttrs, transaction);
895     HwiP_enableInterrupt(hwAttrs->intNum);
896 
897     if (ret != I2C_STATUS_SUCCESS) {
898         /* Error occured, fall through */
899     }
900     else if (object->transferMode == I2C_MODE_BLOCKING) {
901         /* Wait for the primed transfer to complete */
902         if (SemaphoreP_pend(object->transferComplete, timeout)
903             == SemaphoreP_TIMEOUT) {
904 
905             key = HwiP_disable();
906 
907             /*
908              * Protect against a race condition in which the transfer may
909              * finish immediately after the timeout. If this occurs, we
910              * will preemptively consume the semaphore on the next initiated
911              * transfer.
912              */
913             if (object->headPtr) {
914 
915                 /*
916                  * It's okay to call cancel here since this is blocking mode.
917                  * Cancel will generate a STOP condition and immediately
918                  * return.
919                  */
920                 I2CCC32XX_cancel(handle);
921 
922                 HwiP_restore(key);
923 
924                 /*
925                  *  We must wait until the STOP interrupt occurs. When this
926                  *  occurs, the semaphore will be posted. Since the STOP
927                  *  condition will finish the current burst, we can't
928                  *  unblock the object->mutex until this occurs.
929                  *
930                  *  This may block forever if the slave holds the clock line--
931                  *  rendering the I2C bus un-usable.
932                  */
933                 SemaphoreP_pend(object->transferComplete,
934                     SemaphoreP_WAIT_FOREVER);
935 
936                 transaction->status = I2C_STATUS_TIMEOUT;
937             }
938             else {
939                 HwiP_restore(key);
940             }
941         }
942 
943         ret = transaction->status;
944     }
945 
946     /* Release the lock for this particular I2C handle */
947     SemaphoreP_post(object->mutex);
948 
949     return (ret);
950 }
951