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  *  @file       I2C.h
34  *  @brief      Inter-Integrated Circuit (I2C) Driver
35  *
36  *  @anchor ti_drivers_I2C_Overview
37  *  # Overview
38  *
39  *  The I2C driver is designed to operate as an I2C master and will not
40  *  function as an I2C slave. Multi-master arbitration is not supported;
41  *  therefore, this driver assumes it is the only I2C master on the bus.
42  *  This I2C driver's API set provides the ability to transmit and receive
43  *  data over an I2C bus between the I2C master and I2C slave(s). The
44  *  application is responsible for manipulating and interpreting the data.
45  *
46  *
47  *  <hr>
48  *  @anchor ti_drivers_I2C_Usage
49  *  # Usage
50  *
51  *  This section provides a basic @ref ti_drivers_I2C_Synopsis
52  *  "usage summary" and a set of @ref ti_drivers_I2C_Examples "examples"
53  *  in the form of commented code fragments. Detailed descriptions of the
54  *  I2C APIs and their effect are provided in subsequent sections.
55  *
56  *  @anchor ti_drivers_I2C_Synopsis
57  *  ## Synopsis #
58  *  @anchor ti_drivers_I2C_Synopsis_Code
59  *  @code
60  *  // Import I2C Driver definitions
61  *  #include <ti/drivers/I2C.h>
62  *
63  *  // Define name for an index of an I2C bus
64  *  #define SENSORS 0
65  *
66  *  // Define the slave address of device on the SENSORS bus
67  *  #define OPT_ADDR 0x47
68  *
69  *  // One-time init of I2C driver
70  *  I2C_init();
71  *
72  *  // initialize optional I2C bus parameters
73  *  I2C_Params params;
74  *  I2C_Params_init(&params);
75  *  params.bitRate = I2C_400kHz;
76  *
77  *  // Open I2C bus for usage
78  *  I2C_Handle i2cHandle = I2C_open(SENSORS, &params);
79  *
80  *  // Initialize slave address of transaction
81  *  I2C_Transaction transaction = {0};
82  *  transaction.slaveAddress = OPT_ADDR;
83  *
84  *  // Read from I2C slave device
85  *  transaction.readBuf = data;
86  *  transaction.readCount = sizeof(data);
87  *  transaction.writeCount = 0;
88  *  I2C_transfer(i2cHandle, &transaction);
89  *
90  *  // Write to I2C slave device
91  *  transaction.writeBuf = command;
92  *  transaction.writeCount = sizeof(command);
93  *  transaction.readCount = 0;
94  *  I2C_transferTimeout(i2cHandle, &transaction, 5000);
95  *
96  *  // Close I2C
97  *  I2C_close(i2cHandle);
98  *  @endcode
99  *
100  *  @anchor ti_drivers_I2C_Examples
101  *  ## Examples
102  *
103  *  @li @ref ti_drivers_I2C_Example_open "Getting an I2C bus handle"
104  *  @li @ref ti_drivers_I2C_Example_write3bytes "Sending 3 bytes"
105  *  @li @ref ti_drivers_I2C_Example_read5bytes "Reading 5 bytes"
106  *  @li @ref ti_drivers_I2C_Example_writeread "Writing then reading in a single transaction"
107  *  @li @ref ti_drivers_I2C_Example_callback "Using Callback mode"
108  *
109  *  @anchor ti_drivers_I2C_Example_open
110  *  ## Opening the I2C Driver
111  *
112  *  After calling I2C_init(), the application can open an I2C instance by
113  *  calling I2C_open().The following code example opens an I2C instance with
114  *  default parameters by passing @p NULL for the #I2C_Params argument.
115  *
116  *  @code
117  *  I2C_Handle i2cHandle;
118  *
119  *  i2cHandle = I2C_open(0, NULL);
120  *
121  *  if (i2cHandle == NULL) {
122  *      // Error opening I2C
123  *      while (1) {}
124  *  }
125  *  @endcode
126  *
127  *  @anchor ti_drivers_I2C_Example_write3bytes
128  *  ## Sending three bytes of data.
129  *
130  *  @code
131  *  I2C_Transaction i2cTransaction = {0};
132  *  uint8_t writeBuffer[3];
133  *
134  *  writeBuffer[0] = 0xAB;
135  *  writeBuffer[1] = 0xCD;
136  *  writeBuffer[2] = 0xEF;
137  *
138  *  i2cTransaction.slaveAddress = 0x50;
139  *  i2cTransaction.writeBuf = writeBuffer;
140  *  i2cTransaction.writeCount = 3;
141  *  i2cTransaction.readBuf = NULL;
142  *  i2cTransaction.readCount = 0;
143  *
144  *  status = I2C_transfer(i2cHandle, &i2cTransaction);
145  *
146  *  if (status == false) {
147  *      // Unsuccessful I2C transfer
148  *      if (i2cTransaction.status == I2C_STATUS_ADDR_NACK) {
149  *          // I2C slave address not acknowledged
150  *      }
151  *  }
152  *  @endcode
153  *
154  *  @anchor ti_drivers_I2C_Example_read5bytes
155  *  ## Reading five bytes of data.
156  *
157  *  @code
158  *  I2C_Transaction i2cTransaction = {0};
159  *  uint8_t readBuffer[5];
160  *
161  *  i2cTransaction.slaveAddress = 0x50;
162  *  i2cTransaction.writeBuf = NULL;
163  *  i2cTransaction.writeCount = 0;
164  *  i2cTransaction.readBuf = readBuffer;
165  *  i2cTransaction.readCount = 5;
166  *
167  *  status = I2C_transfer(i2cHandle, &i2cTransaction);
168  *
169  *  if (status == false) {
170  *      if (i2cTransaction.status == I2C_STATUS_ADDR_NACK) {
171  *          // I2C slave address not acknowledged
172  *      }
173  *  }
174  *  @endcode
175  *
176  *  @anchor ti_drivers_I2C_Example_writeread
177  *  ## Writing two bytes and reading four bytes in a single transaction.
178  *
179  *  @code
180  *  I2C_Transaction i2cTransaction = {0};
181  *  uint8_t readBuffer[4];
182  *  uint8_t writeBuffer[2];
183  *
184  *  writeBuffer[0] = 0xAB;
185  *  writeBuffer[1] = 0xCD;
186  *
187  *  i2cTransaction.slaveAddress = 0x50;
188  *  i2cTransaction.writeBuf = writeBuffer;
189  *  i2cTransaction.writeCount = 2;
190  *  i2cTransaction.readBuf = readBuffer;
191  *  i2cTransaction.readCount = 4;
192  *
193  *  status = I2C_transfer(i2cHandle, &i2cTransaction);
194  *
195  *  if (status == false) {
196 *       if (i2cTransaction->status == I2C_STATUS_ADDR_NACK) {
197 *           // slave address not acknowledged
198 *       }
199  *  }
200  *  @endcode
201  *
202  *  @anchor ti_drivers_I2C_Example_callback
203  *  ## Using callback mode
204  *  This final example shows usage of #I2C_MODE_CALLBACK, with queuing
205  *  of multiple transactions. Because multiple transactions are simultaneously
206  *  queued, separate #I2C_Transaction structures must be used. Each
207  *  #I2C_Transaction will contain a custom application argument of a
208  *  semaphore handle. The #I2C_Transaction.arg will point to the semaphore
209  *  handle. When the callback function is called, the #I2C_Transaction.arg is
210  *  checked for @p NULL. If this value is not @p NULL, then it can be assumed
211  *  the @p arg is pointing to a valid semaphore handle. The semaphore handle
212  *  is then used to call @p sem_post(). Hypothetically, this can be used to
213  *  signal transaction completion to the task(s) that queued the
214  *  transaction(s).
215  *
216  *  @code
217  *  void callbackFxn(I2C_Handle handle, I2C_Transaction *msg, bool status)
218  *  {
219  *      // if transaction failed
220  *      if (status == false) {
221  *          if (msg->status == I2C_STATUS_ADDR_NACK) {
222  *              // slave address not acknowledged
223  *          }
224  *          else if (msg->status == I2C_STATUS_CANCEL) {
225  *              // transaction canceled by I2C_cancel()
226  *          }
227  *      }
228  *
229  *      // Check for a custom argument
230  *      if (msg->arg != NULL) {
231  *
232  *          // In this example, the custom argument is a semaphore handle
233  *          // Perform a semaphore post
234  *          sem_post((sem_t *) (msg->arg));
235  *      }
236  *  }
237  *  @endcode
238  *
239  *  Snippets of the thread code that initiates the transactions are shown below.
240  *  Note the use of multiple #I2C_Transaction structures. The handle of the
241  *  semaphore to be posted is specified via @p i2cTransaction2.arg.
242  *  I2C_transfer() is called three times to initiate each transaction.
243  *  Since callback mode is used, these functions return immediately. After
244  *  the transactions have been queued, other work can be done. Eventually,
245  *  @p sem_wait() is called causing the thread to block until the transaction
246  *  completes. When the transaction completes, the application's callback
247  *  function, @p callbackFxn will be called. Once #I2C_CallbackFxn posts the
248  *  semaphore, the thread will be unblocked and can resume execution.
249  *
250  *  @code
251  *  void thread(arg0, arg1)
252  *  {
253  *
254  *      I2C_Transaction i2cTransaction0 = {0};
255  *      I2C_Transaction i2cTransaction1 = {0};
256  *      I2C_Transaction i2cTransaction2 = {0};
257  *
258  *      // ...
259  *
260  *      i2cTransaction0.arg = NULL;
261  *      i2cTransaction1.arg = NULL;
262  *      i2cTransaction2.arg = semaphoreHandle;
263  *
264  *      // ...
265  *
266  *      I2C_transfer(i2c, &i2cTransaction0);
267  *      I2C_transfer(i2c, &i2cTransaction1);
268  *      I2C_transfer(i2c, &i2cTransaction2);
269  *
270  *      // ...
271  *
272  *      sem_wait(semaphoreHandle);
273  *  }
274  *  @endcode
275  *
276  *  <hr>
277  *  @anchor ti_drivers_I2C_Configuration
278  *  # Configuration
279  *
280  *  Refer to the @ref driver_configuration "Driver's Configuration" section
281  *  for driver configuration information.
282  *  <hr>
283  ******************************************************************************
284  */
285 
286 #ifndef ti_drivers_I2C__include
287 #define ti_drivers_I2C__include
288 
289 /*! @cond */
290 #include <stdbool.h>
291 #include <stddef.h>
292 #include <stdint.h>
293 /*! @endcond */
294 
295 #ifdef __cplusplus
296 extern "C" {
297 #endif
298 
299 /**
300  *  @defgroup I2C_STATUS I2C Status codes
301  *  These macros are reservations for I2C.h
302  *  @{
303  */
304 
305 /*! @cond */
306 /*!
307  * @private
308  * Common I2C_control status code reservation offset.
309  * I2C driver implementations should offset status codes with
310  * #I2C_STATUS_RESERVED growing negatively.
311  *
312  * Example implementation specific status codes:
313  * @code
314  * #define I2CXYZ_STATUS_ERROR0     I2C_STATUS_RESERVED - 0
315  * #define I2CXYZ_STATUS_ERROR1     I2C_STATUS_RESERVED - 1
316  * #define I2CXYZ_STATUS_ERROR2     I2C_STATUS_RESERVED - 2
317  * @endcode
318  */
319 #define I2C_STATUS_RESERVED        (-32)
320 /*! @endcond */
321 
322 /*!
323  * @brief  I2C transaction is queued but has not started
324  */
325 #define I2C_STATUS_QUEUED          (1)
326 
327 /*!
328  * @brief  Successful status code returned by I2C API.
329  */
330 #define I2C_STATUS_SUCCESS         (0)
331 
332 /*!
333  * @brief  Generic error status code returned by I2C API.
334  */
335 #define I2C_STATUS_ERROR           (-1)
336 
337 /*!
338  * @brief  An error status code returned by I2C_control() for undefined
339  * command codes.
340  */
341 #define I2C_STATUS_UNDEFINEDCMD    (-2)
342 
343 /*!
344  * @brief  I2C operation timed-out
345  */
346 #define I2C_STATUS_TIMEOUT         (-3)
347 
348 /*!
349  * @brief  I2C serial clock line timeout
350  */
351 #define I2C_STATUS_CLOCK_TIMEOUT   (-4)
352 
353 /*!
354  * @brief  I2C slave address not acknowledged
355  */
356 #define I2C_STATUS_ADDR_NACK       (-5)
357 
358 /*!
359  * @brief  I2C data byte not acknowledged
360  */
361 #define I2C_STATUS_DATA_NACK       (-6)
362 
363 /*!
364  * @brief  I2C multi-master arbitration lost
365  */
366 #define I2C_STATUS_ARB_LOST        (-7)
367 
368 /*!
369  * @brief  I2C transaction is in progress or returned without completing
370  */
371 #define I2C_STATUS_INCOMPLETE      (-8)
372 
373 /*!
374  * @brief  I2C bus already in use by another controller. The I2C transaction
375  * was therefore unable to start.
376  */
377 #define I2C_STATUS_BUS_BUSY        (-9)
378 
379 /*!
380  * @brief  I2C transaction canceled by I2C_cancel()
381  */
382 #define I2C_STATUS_CANCEL          (-10)
383 
384 /*!
385  * @brief  I2C transaction is invalid. This may occur if:
386  *   1. The #I2C_Transaction.readCount and #I2C_Transaction.writeCount are
387  *      both set to 0.
388  *   2. A call to I2C_transfer() is made from a #I2C_CallbackFxn while queued
389  *      transactions are being canceled. See also: I2C_cancel()
390  */
391 #define I2C_STATUS_INVALID_TRANS   (-11)
392 /** @} */
393 
394 /*!
395  *  @brief  Wait forever define used to specify timeouts.
396  */
397 #define I2C_WAIT_FOREVER           (~(0U))
398 
399 /*!
400  *  @brief      A handle that is returned from an I2C_open() call.
401  */
402 typedef struct I2C_Config_ *I2C_Handle;
403 
404 /*!
405  *  @brief  Defines a transaction to be used with I2C_transfer() or
406  *          I2C_transferTimeout()
407  *
408  *  After a call to I2C_transfer(), the #I2C_Transaction.status reflects
409  *  the current transfer status.
410  *
411  *  @sa I2C_transfer(), I2C_transferTimeout()
412  */
413 typedef struct {
414     /*!
415      *  Pointer to a buffer of at least #I2C_Transaction.writeCount bytes.
416      *  If #I2C_Transaction.writeCount is 0, this pointer is not used.
417      */
418     void         *writeBuf;
419 
420     /*!
421      *  Number of bytes to write to the I2C slave device. A value of 0
422      *  indicates no data will be written to the slave device and only a read
423      *  will occur. If this value
424      *  is not 0, the driver will always perform the write transfer first.
425      *  The data written to the I2C bus is preceded by the
426      *  #I2C_Transaction.slaveAddress with the write bit set. If
427      *  @p writeCount bytes are successfully sent and
428      *  acknowledged, the transfer will complete or perform a read--depending
429      *  on #I2C_Transaction.readCount.
430      *
431      *  @note Both #I2C_Transaction.writeCount and #I2C_Transaction.readCount
432      *  can not be 0.
433      */
434     size_t        writeCount;
435 
436     /*!
437      *  Pointer to a buffer of at least #I2C_Transaction.readCount bytes.
438      *  If #I2C_Transaction.readCount is 0, this pointer is not used.
439      */
440     void         *readBuf;
441 
442     /*!
443      *  Number of bytes to read from the I2C slave device. A value of 0
444      *  indicates no data will be read and only a write will occur. If
445      *  #I2C_Transaction.writeCount is not 0, this driver will perform the
446      *  write first, followed by the read. The data read from the bus is
447      *  preceded by the #I2C_Transaction.slaveAddress with the read bit set.
448      *  After @p readCount bytes are successfully read, the transfer will
449      *  complete.
450      *
451      *  @note Both #I2C_Transaction.writeCount and #I2C_Transaction.readCount
452      *  can not be 0.
453      */
454     size_t        readCount;
455 
456     /*!
457      * Pointer to a custom argument to be passed to the #I2C_CallbackFxn
458      * function via the #I2C_Transaction structure.
459      *
460      * @note The #I2C_CallbackFxn function is only called when operating in
461      * #I2C_MODE_CALLBACK.
462      *
463      * @sa  #I2C_MODE_CALLBACK
464      * @sa  #I2C_CallbackFxn
465      */
466     void         *arg;
467 
468     /*!
469      *  I2C status of the current transaction. The status may be used to
470      *  determine why a transaction failed. Potential codes are:
471      *      @li #I2C_STATUS_SUCCESS
472      *      @li #I2C_STATUS_ERROR
473      *      @li #I2C_STATUS_TIMEOUT
474      *      @li #I2C_STATUS_CLOCK_TIMEOUT
475      *      @li #I2C_STATUS_ADDR_NACK
476      *      @li #I2C_STATUS_DATA_NACK
477      *      @li #I2C_STATUS_ARB_LOST
478      *      @li #I2C_STATUS_INCOMPLETE
479      *      @li #I2C_STATUS_BUS_BUSY
480      *      @li #I2C_STATUS_CANCEL
481      *      @li #I2C_STATUS_INVALID_TRANS
482      *
483      *  This status may also be used to determine if a transaction is queued
484      *  (#I2C_STATUS_QUEUED) or in progress (#I2C_STATUS_INCOMPLETE).
485      */
486     volatile int_fast16_t status;
487 
488     /*!
489      *  I2C slave address used for the transaction. The slave address is
490      *  the first byte transmitted during an I2C transfer. The read/write bit
491      *  is automatically set based upon the #I2C_Transaction.writeCount and
492      *  #I2C_Transaction.readCount.
493      */
494     uint_least8_t slaveAddress;
495 
496     /*!
497      *  @private This is reserved for use by the driver and must never be
498      *  modified by the application.
499      */
500     void         *nextPtr;
501 } I2C_Transaction;
502 
503 /*!
504  *  @brief    Return behavior of I2C_Transfer() specified in the #I2C_Params.
505  *
506  *  This enumeration defines the return behaviors for a call to I2C_transfer().
507  *
508  *  @sa  #I2C_Params
509  */
510 typedef enum {
511     /*!
512      *  In #I2C_MODE_BLOCKING, calls to I2C_transfer() block until the
513      *  #I2C_Transaction completes. Other threads calling I2C_transfer()
514      *  while a transaction is in progress are also placed into a blocked
515      *  state. If multiple threads are blocked, the thread with the highest
516      *  priority will be unblocked first. This implies that arbitration
517      *  will not be executed in chronological order.
518      *
519      *  @note When using #I2C_MODE_BLOCKING, I2C_transfer() must be called
520      *  from a thread context.
521      */
522     I2C_MODE_BLOCKING,
523 
524     /*!
525      *  In #I2C_MODE_CALLBACK, calls to I2C_transfer() return immediately. The
526      *  application's callback function, #I2C_Params.transferCallbackFxn, is
527      *  called when the transaction is complete. Sequential calls to
528      *  I2C_transfer() will place #I2C_Transaction structures into an
529      *  internal queue. Queued transactions are automatically started after the
530      *  previous transaction has completed. This queuing occurs regardless of
531      *  any error state from previous transactions. The transactions are
532      *  always executed in chronological order. The
533      *  #I2C_Params.transferCallbackFxn function will be called asynchronously
534      *  as each transaction is completed.
535      */
536     I2C_MODE_CALLBACK
537 } I2C_TransferMode;
538 
539 /*!
540  *  @brief  The definition of a callback function.
541  *
542  *  When operating in #I2C_MODE_CALLBACK, the callback function is called
543  *  when an I2C_transfer() completes. The application is responsible for
544  *  declaring an #I2C_CallbackFxn function and providing a pointer
545  *  in #I2C_Params.transferCallbackFxn.
546  *
547  *  @warning  The callback function is called from an interrupt context.
548  *
549  *  @param[out]  handle    #I2C_Handle used with the initial call to
550  *  I2C_transfer()
551  *
552  *  @param[out]  transaction    Pointer to the #I2C_Transaction structure used
553  *  with the initial call to I2C_transfer(). This structure contains the
554  *  custom argument specified by @p transaction.arg and the transaction status.
555  *
556  *  @param[out]  transferStatus    Boolean indicating if the I2C transaction
557  *  was successful. If @p true, the transaction was successful. If @p false,
558  *  the transaction failed.
559  */
560 typedef void (*I2C_CallbackFxn)(I2C_Handle handle, I2C_Transaction *transaction,
561     bool transferStatus);
562 
563 /*!
564  *  @brief  Bit rate for an I2C driver instance specified in the #I2C_Params.
565  *
566  *  This enumeration defines the bit rates used with an I2C_transfer().
567  *
568  *  @note You must check that the device specific implementation supports the
569  *  desired #I2C_BitRate.
570  */
571 typedef enum {
572     I2C_100kHz     = 0,    /*!< I2C Standard-mode. Up to 100 kbit/s. */
573     I2C_400kHz     = 1,    /*!< I2C Fast-mode. Up to 400 kbit/s. */
574     I2C_1000kHz    = 2,    /*!< I2C Fast-mode Plus. Up to 1Mbit/s. */
575     I2C_3330kHz    = 3,    /*!< I2C High-speed mode. Up to 3.4Mbit/s. */
576     I2C_3400kHz    = 3,    /*!< I2C High-speed mode. Up to 3.4Mbit/s. */
577 } I2C_BitRate;
578 
579 /*!
580  *  @brief I2C parameters used with I2C_open().
581  *
582  *  I2C_Params_init() must be called prior to setting fields in
583  *  this structure.
584  *
585  *  @sa  I2C_Params_init()
586  */
587 typedef struct {
588     /*! #I2C_TransferMode for all I2C transfers. */
589     I2C_TransferMode transferMode;
590 
591     /*!
592      *  Pointer to a #I2C_CallbackFxn to be invoked after a
593      *  I2C_transfer() completes when operating in #I2C_MODE_CALLBACK.
594      */
595     I2C_CallbackFxn transferCallbackFxn;
596 
597     /*!
598      * A #I2C_BitRate specifying the frequency at which the I2C peripheral
599      * will transmit data during a I2C_transfer().
600      */
601     I2C_BitRate bitRate;
602 
603     /*! Pointer to a device specific extension of the #I2C_Params */
604     void *custom;
605 } I2C_Params;
606 
607 /*!
608  *  @private
609  *  @brief      A function pointer to a driver-specific implementation of
610  *              I2C_cancel().
611  */
612 typedef void (*I2C_CancelFxn) (I2C_Handle handle);
613 
614 /*!
615  *  @private
616  *  @brief      A function pointer to a driver-specific implementation of
617  *              I2C_close().
618  */
619 typedef void (*I2C_CloseFxn) (I2C_Handle handle);
620 
621 /*!
622  *  @private
623  *  @brief      A function pointer to a driver-specific implementation of
624  *              I2C_control().
625  */
626 typedef int_fast16_t (*I2C_ControlFxn) (I2C_Handle handle, uint_fast16_t cmd,
627     void *controlArg);
628 
629 /*!
630  *  @private
631  *  @brief      A function pointer to a driver-specific implementation of
632  *              I2C_init().
633  */
634 typedef void (*I2C_InitFxn) (I2C_Handle handle);
635 
636 /*!
637  *  @private
638  *  @brief      A function pointer to a driver-specific implementation of
639  *              I2C_open().
640  */
641 typedef I2C_Handle (*I2C_OpenFxn) (I2C_Handle handle, I2C_Params *params);
642 
643 /*!
644  *  @private
645  *  @brief      A function pointer to a driver-specific implementation of
646  *              I2C_transfer().
647  */
648 typedef int_fast16_t (*I2C_TransferFxn) (I2C_Handle handle,
649                       I2C_Transaction *transaction, uint32_t timeout);
650 
651 /*!
652  *  @brief      The definition of an I2C function table that contains the
653  *              required set of functions to control a specific I2C driver
654  *              implementation.
655  */
656 typedef struct {
657     I2C_CancelFxn   cancelFxn;
658     I2C_CloseFxn    closeFxn;
659     I2C_ControlFxn  controlFxn;
660     I2C_InitFxn     initFxn;
661     I2C_OpenFxn     openFxn;
662     I2C_TransferFxn transferFxn;
663 } I2C_FxnTable;
664 
665 /*!
666  *  @brief I2C driver's custom @ref driver_configuration "configuration"
667  *  structure.
668  *
669  *  @sa     I2C_init()
670  *  @sa     I2C_open()
671  */
672 typedef struct I2C_Config_ {
673     /*! Pointer to a @ref driver_function_table "function pointer table"
674      *  with driver-specific implementations of I2C APIs */
675     I2C_FxnTable const *fxnTablePtr;
676 
677     /*! Pointer to a driver specific @ref driver_objects "data object". */
678     void               *object;
679 
680     /*! Pointer to a driver specific @ref driver_hardware_attributes
681      *  "hardware attributes structure". */
682     void         const *hwAttrs;
683 } I2C_Config;
684 
685 /*!
686  *  @brief  Cancels all I2C transfers
687  *
688  *  This function will cancel asynchronous I2C_transfer() operations by
689  *  generating a STOP condition on the I2C bus.
690  *
691  *  Calls to I2C_cancel() return immediately; however, the transaction
692  *  may not yet be canceled.
693  *
694  *  For #I2C_MODE_BLOCKING, the current transaction is canceled.
695  *
696  *  For #I2C_MODE_CALLBACK mode, the in progress transfer, as
697  *  well as any queued transfers, will be canceled. The individual callback
698  *  functions for each transfer will be called in chronological order. The
699  *  callback functions are called in an interrupt context. Additional calls
700  *  to I2C_transfer() invoked from the callback function of a canceled
701  *  transaction will always fail. In such cases, the #I2C_Transaction.status
702  *  will indicate #I2C_STATUS_INVALID_TRANS.
703  *
704  *  A canceled transaction may be identified when the #I2C_Transaction.status
705  *  is set to #I2C_STATUS_CANCEL.
706  *
707  *  @note This API may not handle cases where the I2C slave holds the clock
708  *  line indefinitely.
709  *
710  *  @pre    I2C_Transfer() has been called.
711  *
712  *  @param[in]  handle  An #I2C_Handle returned from I2C_open()
713  *
714  *  @note   Different I2C slave devices will behave differently when an
715  *          in-progress transfer fails and needs to be canceled. The slave
716  *          may need to be reset, or there may be other slave-specific
717  *          steps that can be used to successfully resume communication.
718  *
719  *  @sa  I2C_transfer()
720  *  @sa  #I2C_MODE_CALLBACK
721  */
722 extern void I2C_cancel(I2C_Handle handle);
723 
724 /*!
725  *  @brief  Function to close an I2C driver instance
726  *
727  *  @pre  I2C_open() has been called.
728  *
729  *  @param[in]  handle  An #I2C_Handle returned from I2C_open()
730  */
731 extern void I2C_close(I2C_Handle handle);
732 
733 /*!
734  *  @brief  Function performs implementation specific features on a
735  *          driver instance.
736  *
737  *  @pre    I2C_open() has to be called first.
738  *
739  *  @param[in]  handle   An #I2C_Handle returned from I2C_open()
740  *
741  *  @param[in]  cmd     A command value defined by the device specific
742  *                      implementation
743  *
744  *  @param[in]  controlArg    An optional R/W (read/write) argument that is
745  *                            accompanied with @p cmd
746  *
747  *  @return Implementation specific return codes. Negative values indicate
748  *          unsuccessful operations.
749  *
750  *  @retval #I2C_STATUS_SUCCESS The call was successful.
751  *  @retval #I2C_STATUS_UNDEFINEDCMD The @p cmd value is not supported by
752  *                                   the device specific implementation.
753  */
754 extern int_fast16_t I2C_control(I2C_Handle handle, uint_fast16_t cmd,
755     void *controlArg);
756 
757 /*!
758  *  @brief  Function to initialize the I2C driver.
759  *
760  *  This function must also be called before any otherI2C driver APIs.
761  */
762 extern void I2C_init(void);
763 
764 /*!
765  *  @brief  Open an I2C driver instance.
766  *
767  *  @pre    I2C_init() has been called.
768  *
769  *  @param[in]  index    Index in the @p I2C_Config[] array.
770  *
771  *  @param[in]  params    Pointer to an initialized #I2C_Params structure.
772  *                        If NULL, the default #I2C_Params values are used.
773  *
774  *  @return An #I2C_Handle on success, or @p NULL on an error.
775  *
776  *  @sa     I2C_init()
777  *  @sa     I2C_close()
778  */
779 extern I2C_Handle I2C_open(uint_least8_t index, I2C_Params *params);
780 
781 /*!
782  *  @brief  Initialize an #I2C_Params structure to its default values.
783  *
784  *  @param[in]  params    A pointer to #I2C_Params structure for
785  *                        initialization.
786  *
787  *  Defaults values are:
788  *  @arg #I2C_Params.transferMode = #I2C_MODE_BLOCKING
789  *  @arg #I2C_Params.transferCallbackFxn = @p NULL
790  *  @arg #I2C_Params.bitRate = #I2C_100kHz
791  *  @arg #I2C_Params.custom = @p NULL
792  */
793 extern void I2C_Params_init(I2C_Params *params);
794 
795 /*!
796  *  @brief  Perform an I2C transaction with an I2C slave peripheral.
797  *
798  *  This function will perform an I2C transfer, as specified by an
799  *  #I2C_Transaction structure.
800  *
801  *  @note When using #I2C_MODE_BLOCKING, this must be called from a thread
802  *  context.
803  *
804  *  @param[in]  handle      An #I2C_Handle returned from I2C_open()
805  *
806  *  @param[in]  transaction  A pointer to an #I2C_Transaction. The application
807  *  is responsible for allocating and initializing an #I2C_Transaction
808  *  structure prior to passing it to I2C_Transfer(). This
809  *  structure must persist in memory unmodified until the transfer is complete.
810  *
811  *  @note #I2C_Transaction structures cannot be re-used until the previous
812  *  transaction has completed. Upon the completion of a transaction, the
813  *  #I2C_Transaction.status may be used for error handling.
814  *
815  *  @return In #I2C_MODE_BLOCKING: @p true for a successful transfer; @p false
816  *          for an error (for example, an I2C bus fault (NACK)).
817  *
818  *  @return In #I2C_MODE_CALLBACK: always @p true. The #I2C_CallbackFxn @p bool
819  *          argument will be @p true to indicate success, and @p false to
820  *          indicate an error.
821  *
822  *  @pre I2C_open() has been called.
823  *
824  *  @sa  I2C_open(), I2C_transferTimeout()
825  *  @sa  I2C_Transaction
826  */
827 extern bool I2C_transfer(I2C_Handle handle, I2C_Transaction *transaction);
828 
829 /*!
830  *  @brief  Perform an I2C transaction with an I2C slave peripheral.
831  *
832  *  This function will perform an I2C transfer, as specified by an
833  *  #I2C_Transaction structure. If the timeout is exceeded, then the
834  *  I2C transaction is canceled.
835  *
836  *  @note When using #I2C_MODE_BLOCKING, this must be called from a thread
837  *  context.
838  *
839  *  @note  The timeout restriction is only applied when using
840  *  #I2C_MODE_BLOCKING. If using #I2C_MODE_CALLBACK, the application should
841  *  manage timeouts using I2C_cancel(). Additionally, this timeout may not
842  *  handle cases where the I2C slave holds the clock line indefinitely.
843  *
844  *  @param[in]  handle    An #I2C_Handle returned from I2C_open()
845  *
846  *  @param[in]  transaction  A pointer to an #I2C_Transaction. The application
847  *  is responsible for allocating and initializing an #I2C_Transaction
848  *  structure prior to passing it to I2C_TransferTimeout(). This
849  *  structure must persist in memory unmodified until the transfer is complete.
850  *
851  *  @param[in]  timeout    The time in system ticks to wait for the transaction
852  *  to complete. Passing I2C_WAIT_FOREVER into this parameter will cause
853  *  I2C_transferTimeout() to behave the same as I2C_transfer() but with a
854  *  more detailed return status.
855  *
856  *  @note #I2C_Transaction structures cannot be re-used until the previous
857  *  transaction has completed. Upon the completion of a transaction, the
858  *  #I2C_Transaction.status may be used for error handling.
859  *
860  *  @return  In #I2C_MODE_CALLBACK: always @p I2C_STATUS_SUCCESS.
861  *           The #I2C_CallbackFxn @p transferStatus argument will be @p true
862  *           to indicate success, and @p false to indicate an error.
863  *
864  *  @return  In #I2C_MODE_BLOCKING: Possible return values include:
865  *            @li #I2C_STATUS_SUCCESS
866  *            @li #I2C_STATUS_ERROR
867  *            @li #I2C_STATUS_TIMEOUT
868  *            @li #I2C_STATUS_CLOCK_TIMEOUT
869  *            @li #I2C_STATUS_ADDR_NACK
870  *            @li #I2C_STATUS_DATA_NACK
871  *            @li #I2C_STATUS_ARB_LOST
872  *            @li #I2C_STATUS_INCOMPLETE
873  *            @li #I2C_STATUS_BUS_BUSY
874  *            @li #I2C_STATUS_CANCEL
875  *            @li #I2C_STATUS_INVALID_TRANS
876  *
877  *  @pre I2C_open() has been called.
878  *
879  *  @sa  I2C_open(), I2C_transfer()
880  *  @sa  I2C_Transaction
881  */
882 extern int_fast16_t I2C_transferTimeout(I2C_Handle handle,
883     I2C_Transaction *transaction, uint32_t timeout);
884 
885 #ifdef __cplusplus
886 }
887 #endif
888 
889 #endif /* ti_drivers_I2C__include */
890