| /* |
| * Copyright (c) 2015-2016, Texas Instruments Incorporated |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * |
| * * Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * * Neither the name of Texas Instruments Incorporated nor the names of |
| * its contributors may be used to endorse or promote products derived |
| * from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
| * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
| * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
| * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| /*!***************************************************************************** |
| * @file I2C.h |
| * |
| * @brief I2C driver interface |
| * |
| * The I2C driver interface provides device independent APIs, data types, |
| * and macros. The I2C header file should be included in an application as |
| * follows: |
| * @code |
| * #include <ti/drivers/I2C.h> |
| * @endcode |
| * |
| * # Overview # |
| * This section assumes that you have background knowledge and understanding |
| * about how the I2C protocol operates. For the full I2C specifications and |
| * user manual (UM10204), see the NXP Semiconductors website. |
| * |
| * The I2C driver has been designed to operate as a single I2C master by |
| * performing I2C transactions between the target and I2C slave peripherals. |
| * The I2C driver does not support I2C slave mode. |
| * I2C is a communication protocol - the specifications define how data |
| * transactions are to occur via the I2C bus. The specifications do not |
| * define how data is to be formatted or handled, allowing for flexible |
| * implementations across different peripheral vendors. As a result, the |
| * I2C handles only the exchange of data (or transactions) between master |
| * and slaves. It is the left to the application to interpret and |
| * manipulate the contents of each specific I2C peripheral. |
| * |
| * The I2C driver has been designed to operate in an RTOS environment. It |
| * protects its transactions with OS primitives supplied by the underlying |
| * RTOS. |
| * |
| * # Usage # |
| * |
| * The I2C driver includes the following APIs: |
| * - I2C_init(): Initialize the I2C driver. |
| * - I2C_Params_init(): Initialize an #I2C_Params structure with default |
| * vaules. |
| * - I2C_open(): Open an instance of the I2C driver. |
| * - I2C_control(): Performs implemenation-specific features on a given |
| * I2C peripheral. |
| * - I2C_transfer(): Transfer the data. |
| * - I2C_close(): De-initialize the I2C instance. |
| * |
| * |
| * ### I2C Driver Configuration # |
| * |
| * In order to use the I2C APIs, the application is required |
| * to provide device-specific I2C configuration in the Board.c file. |
| * The I2C driver interface defines a configuration data structure: |
| * |
| * @code |
| * typedef struct I2C_Config_ { |
| * I2C_FxnTable const *fxnTablePtr; |
| * void *object; |
| * void const *hwAttrs; |
| * } I2C_Config; |
| * @endcode |
| * |
| * The application must declare an array of I2C_Config elements, named |
| * I2C_config[]. Each element of I2C_config[] must be populated with |
| * pointers to a device specific I2C driver implementation's function |
| * table, driver object, and hardware attributes. The hardware attributes |
| * define properties such as the I2C peripheral's base address and |
| * pins. Each element in I2C_config[] corresponds to |
| * an I2C instance, and none of the elements should have NULL pointers. |
| * There is no correlation between the index and the |
| * peripheral designation (such as I2C0 or I2C1). For example, it is |
| * possible to use I2C_config[0] for I2C1. |
| * |
| * Because the I2C configuration is very device dependent, you will need to |
| * check the doxygen for the device specific I2C implementation. There you |
| * will find a description of the I2C hardware attributes. Please also |
| * refer to the Board.c file of any of your examples to see the I2C |
| * configuration. |
| * |
| * ### Initializing the I2C Driver # |
| * |
| * I2C_init() must be called before any other I2C APIs. This function |
| * iterates through the elements of the I2C_config[] array, calling |
| * the element's device implementation I2C initialization function. |
| * |
| * ### I2C Parameters |
| * |
| * The #I2C_Params structure is passed to the I2C_open() call. If NULL |
| * is passed for the parameters, I2C_open() uses default parameters. |
| * An #I2C_Params structure is initialized with default values by passing |
| * it to I2C_Params_init(). |
| * Some of the I2C parameters are described below. To see brief descriptions |
| * of all the parameters, see #I2C_Params. |
| * |
| * #### I2C Transfer Mode |
| * The I2C driver supports two transfer modes of operation: blocking and |
| * callback: |
| * - #I2C_MODE_BLOCKING: The call to I2C_transfer() blocks until the |
| * transfer completes. |
| * - #I2C_MODE_CALLBACK: The call to I2C_transfer() returns immediately. |
| * When the transfer completes, the I2C driver will call a user- |
| * specified callback function. |
| * |
| * The transfer mode is determined by the #I2C_Params.transferMode parameter |
| * passed to I2C_open(). The I2C driver defaults to blocking mode, if the |
| * application does not set it. |
| * |
| * In blocking mode, a task calling I2C_transfer() is blocked until the |
| * transaction completes. Other tasks requesting I2C transactions while |
| * a transaction is currently taking place, are also placed into a |
| * blocked state. |
| * |
| * In callback mode, an I2C_transfer() functions asynchronously, which |
| * means that it does not block a calling task's execution. In this |
| * mode, the user must set #I2C_Params.transferCallbackFxn to a user- |
| * provided callback function. After an I2C transaction has completed, |
| * the I2C driver calls the user- provided callback function. |
| * If another I2C transaction is requested, the transaction is queued up. |
| * As each transfer completes, the I2C driver will call the user-specified |
| * callback function. The user callback will be called from either hardware |
| * or software interrupt context, depending upon the device implementation. |
| * |
| * Once an I2C driver instance is opened, the |
| * only way to change the transfer mode is to close and re-open the I2C |
| * instance with the new transfer mode. |
| * |
| * #### Specifying an I2C Bus Frequency |
| * The I2C controller's bus frequency is determined by #I2C_Params.bitRate |
| * passed to I2C_open(). The standard I2C bus frequencies are 100 kHz and |
| * 400 kHz, with 100 kHz being the default. |
| * |
| * ### Opening the I2C Driver # |
| * After initializing the I2C driver by calling I2C_init(), the application |
| * can open an I2C instance by calling I2C_open(). This function |
| * takes an index into the I2C_config[] array and an I2C parameters data |
| * structure. The I2C instance is specified by the index of the I2C in |
| * I2C_config[]. Only one I2C index can be used at a time; |
| * calling I2C_open() a second time with the same index previosly |
| * passed to I2C_open() will result in an error. You can, |
| * though, re-use the index if the instance is closed via I2C_close(). |
| * |
| * If no I2C_Params structure is passed to I2C_open(), default values are |
| * used. If the open call is successful, it returns a non-NULL value. |
| * |
| * Example opening an I2C driver instance in blocking mode: |
| * @code |
| * I2C_Handle i2c; |
| * |
| * // NULL params are used, so default to blocking mode, 100 KHz |
| * i2c = I2C_open(Board_I2C0, NULL); |
| * |
| * if (!i2c) { |
| * // Error opening the I2C |
| * } |
| * @endcode |
| * |
| * Example opening an I2C driver instance in callback mode and 400KHz bit rate: |
| * |
| * @code |
| * I2C_Handle i2c; |
| * I2C_Params params; |
| * |
| * I2C_Params_init(¶ms); |
| * params.transferMode = I2C_MODE_CALLBACK; |
| * params.transferCallbackFxn = myCallbackFunction; |
| * params.bitRate = I2C_400kHz; |
| * |
| * handle = I2C_open(Board_I2C0, ¶ms); |
| * if (!i2c) { |
| * // Error opening I2C |
| * } |
| * @endcode |
| * |
| * ### Transferring data # |
| * An I2C transaction with an I2C peripheral is started by calling |
| * I2C_transfer(). Three types of transactions are supported: Write, Read, |
| * or Write/Read. Each transfer is completed before another transfer is |
| * initiated. |
| * |
| * For Write/Read transactions, the specified data is first written to the |
| * peripheral, then a repeated start is sent by the driver, which initiates |
| * the read operation. This type of transfer is useful if an I2C peripheral |
| * has a pointer register that needs to be adjusted prior to reading from |
| * the referenced data register. |
| * |
| * The details of each transaction are specified with an #I2C_Transaction data |
| * structure. This structure defines the slave I2C address, pointers |
| * to write and read buffers, and their associated byte counts. If |
| * no data needs to be written or read, the corresponding byte counts should |
| * be set to zero. |
| * |
| * If an I2C transaction is requested while a transaction is currently |
| * taking place, the new transaction is placed onto a queue to be processed |
| * in the order in which it was received. |
| * |
| * The below example shows sending three bytes of data to a slave peripheral |
| * at address 0x50, in blocking mode: |
| * |
| * @code |
| * unsigned char writeBuffer[3]; |
| * I2C_Transaction i2cTransaction; |
| * |
| * i2cTransaction.slaveAddress = 0x50; |
| * i2cTransaction.writeBuf = writeBuffer; |
| * i2cTransaction.writeCount = 3; |
| * i2cTransaction.readBuf = NULL; |
| * i2cTransaction.readCount = 0; |
| * |
| * status = I2C_transfer(i2c, &i2cTransaction); |
| * if (!status) { |
| * // Unsuccessful I2C transfer |
| * } |
| * @endcode |
| * |
| * The next example shows reading of five bytes of data from the I2C |
| * peripheral, also in blocking mode: |
| * |
| * @code |
| * unsigned char readBuffer[5]; |
| * I2C_Transaction i2cTransaction; |
| * |
| * i2cTransaction.slaveAddress = 0x50; |
| * i2cTransaction.writeBuf = NULL; |
| * i2cTransaction.writeCount = 0; |
| * i2cTransaction.readBuf = readBuffer; |
| * i2cTransaction.readCount = 5; |
| * |
| * status = I2C_transfer(i2c, &i2cTransaction); |
| * if (!status) { |
| * // Unsuccessful I2C transfer |
| * } |
| * @endcode |
| * |
| * This example shows writing of two bytes and reading of four bytes in a |
| * single transaction. |
| * |
| * @code |
| * unsigned char readBuffer[4]; |
| * unsigned char writeBuffer[2]; |
| * I2C_Transaction i2cTransaction; |
| * |
| * i2cTransaction.slaveAddress = 0x50; |
| * i2cTransaction.writeBuf = writeBuffer; |
| * i2cTransaction.writeCount = 2; |
| * i2cTransaction.readBuf = readBuffer; |
| * i2cTransaction.readCount = 4; |
| * |
| * status = I2C_transfer(i2c, &i2cTransaction); |
| * if (!status) { |
| * // Unsuccessful I2C transfer |
| * } |
| * @endcode |
| * |
| * This final example shows usage of asynchronous callback mode, with queuing |
| * of multiple transactions. Because multiple transactions are simultaneously |
| * queued, separate I2C_Transaction structures must be used. (This is a |
| * general rule, that I2C_Transaction structures cannot be reused until |
| * it is known that the previous transaction has completed.) |
| * |
| * First, for the callback function (that is specified in the I2C_open() call) |
| * the "arg" in the I2C_Transaction structure is a SemaphoreP_Handle; when |
| * this value is non-NULL, SemaphoreP_post() is called in the callback using |
| * the specified handle, to signal completion to the task that queued the |
| * transactions: |
| * |
| * @code |
| * Void callbackFxn(I2C_Handle handle, I2C_Transaction *msg, Bool transfer) { |
| * if (msg->arg != NULL) { |
| * SemaphoreP_post((SemaphoreP_Handle)(msg->arg)); |
| * } |
| * } |
| * @endcode |
| * |
| * Snippets of the task code that initiates the transactions are shown below. |
| * Note the use of multiple I2C_Transaction structures, and passing of the |
| * handle of the semaphore to be posted via i2cTransaction2.arg. |
| * I2C_transfer() is called three times to initiate each transaction. |
| * Since callback mode is used, these functions return immediately. After |
| * the transactions have been queued, other work can be done, and then |
| * eventually SemaphoreP_pend() is called to wait for the last I2C |
| * transaction to complete. Once the callback posts the semaphore, the task |
| * will be moved to the ready state, so the task can resume execution, after |
| * the SemaphoreP_pend() call. |
| * |
| * @code |
| * Void taskfxn(arg0, arg1) { |
| * |
| * I2C_Transaction i2cTransaction0; |
| * I2C_Transaction i2cTransaction1; |
| * I2C_Transaction i2cTransaction2; |
| * |
| * ... |
| * i2cTransaction0.arg = NULL; |
| * i2cTransaction1.arg = NULL; |
| * i2cTransaction2.arg = semaphoreHandle; |
| * |
| * ... |
| * I2C_transfer(i2c, &i2cTransaction0); |
| * I2C_transfer(i2c, &i2cTransaction1); |
| * I2C_transfer(i2c, &i2cTransaction2); |
| * |
| * ... |
| * |
| * SemaphoreP_pend(semaphoreHandle); |
| * |
| * ... |
| * } |
| * @endcode |
| * |
| * # Implementation # |
| * |
| * This top-level I2C module serves as the main interface for RTOS |
| * applications. Its purpose is to redirect the module's APIs to specific |
| * peripheral implementations which are specified using a pointer to an |
| * #I2C_FxnTable. |
| * |
| * The I2C driver interface module is joined (at link time) to an |
| * array of I2C_Config data structures named *I2C_config*. |
| * *I2C_config* is typically defined in the Board.c file used for the |
| * application. If there are multiple instances of I2C peripherals on the |
| * device, there will typically be multiple I2C_Config structures defined in |
| * the board file. Each entry in *I2C_config* contains a: |
| * - (I2C_FxnTable *) to a set of functions that implement a I2C peripheral |
| * - (void *) data object that is associated with the I2C_FxnTable |
| * - (void *) hardware attributes that are associated to the I2C_FxnTable |
| * |
| ******************************************************************************* |
| */ |
| |
| #ifndef ti_drivers_I2C__include |
| #define ti_drivers_I2C__include |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| #include <stdint.h> |
| #include <stdbool.h> |
| #include <stddef.h> |
| |
| /** |
| * @defgroup I2C_CONTROL I2C_control command and status codes |
| * These I2C macros are reservations for I2C.h |
| * @{ |
| */ |
| |
| /*! |
| * Common I2C_control command code reservation offset. |
| * I2C driver implementations should offset command codes with I2C_CMD_RESERVED |
| * growing positively |
| * |
| * Example implementation specific command codes: |
| * @code |
| * #define I2CXYZ_CMD_COMMAND0 I2C_CMD_RESERVED + 0 |
| * #define I2CXYZ_CMD_COMMAND1 I2C_CMD_RESERVED + 1 |
| * @endcode |
| */ |
| #define I2C_CMD_RESERVED (32) |
| |
| /*! |
| * Common I2C_control status code reservation offset. |
| * I2C driver implementations should offset status codes with |
| * I2C_STATUS_RESERVED growing negatively. |
| * |
| * Example implementation specific status codes: |
| * @code |
| * #define I2CXYZ_STATUS_ERROR0 I2C_STATUS_RESERVED - 0 |
| * #define I2CXYZ_STATUS_ERROR1 I2C_STATUS_RESERVED - 1 |
| * #define I2CXYZ_STATUS_ERROR2 I2C_STATUS_RESERVED - 2 |
| * @endcode |
| */ |
| #define I2C_STATUS_RESERVED (-32) |
| |
| /** |
| * @defgroup I2C_STATUS Status Codes |
| * I2C_STATUS_* macros are general status codes returned by I2C_control() |
| * @{ |
| * @ingroup I2C_CONTROL |
| */ |
| |
| /*! |
| * @brief Successful status code returned by I2C_control(). |
| * |
| * I2C_control() returns I2C_STATUS_SUCCESS if the control code was executed |
| * successfully. |
| */ |
| #define I2C_STATUS_SUCCESS (0) |
| |
| /*! |
| * @brief Generic error status code returned by I2C_control(). |
| * |
| * I2C_control() returns I2C_STATUS_ERROR if the control code was not executed |
| * successfully. |
| */ |
| #define I2C_STATUS_ERROR (-1) |
| |
| /*! |
| * @brief An error status code returned by I2C_control() for undefined |
| * command codes. |
| * |
| * I2C_control() returns I2C_STATUS_UNDEFINEDCMD if the control code is not |
| * recognized by the driver implementation. |
| */ |
| #define I2C_STATUS_UNDEFINEDCMD (-2) |
| /** @}*/ |
| |
| /** |
| * @defgroup I2C_CMD Command Codes |
| * I2C_CMD_* macros are general command codes for I2C_control(). Not all I2C |
| * driver implementations support these command codes. |
| * @{ |
| * @ingroup I2C_CONTROL |
| */ |
| |
| /* Add I2C_CMD_<commands> here */ |
| |
| /** @}*/ |
| |
| /** @}*/ |
| |
| /*! |
| * @brief A handle that is returned from an I2C_open() call. |
| */ |
| typedef struct I2C_Config_ *I2C_Handle; |
| |
| /*! |
| * @brief I2C transaction |
| * |
| * This structure defines an I2C transaction. It specifies the buffer(s) and |
| * buffer size(s) to be written to and/or read from an I2C slave peripheral. |
| * arg is an optional user-supplied argument that will be passed |
| * to the user-supplied callback function when the I2C driver is in |
| * I2C_MODE_CALLBACK. |
| * nextPtr is a pointer used internally by the driver for queuing of multiple |
| * transactions; this value must never be modified by the user application. |
| */ |
| typedef struct I2C_Transaction_ { |
| void *writeBuf; /*!< Buffer containing data to be written */ |
| size_t writeCount; /*!< Number of bytes to be written to the slave */ |
| |
| void *readBuf; /*!< Buffer to which data is to be read into */ |
| size_t readCount; /*!< Number of bytes to be read from the slave */ |
| |
| uint_least8_t slaveAddress; /*!< Address of the I2C slave peripheral */ |
| |
| void *arg; /*!< Argument to be passed to the callback function */ |
| void *nextPtr; /*!< Used for queuing in I2C_MODE_CALLBACK mode */ |
| } I2C_Transaction; |
| |
| /*! |
| * @brief I2C transfer mode |
| * |
| * I2C_MODE_BLOCKING blocks task execution while an I2C transfer is in |
| * progress. |
| * I2C_MODE_CALLBACK does not block task execution, but calls a callback |
| * function when the I2C transfer has completed. |
| */ |
| typedef enum I2C_TransferMode_ { |
| I2C_MODE_BLOCKING, /*!< I2C_transfer() blocks execution */ |
| I2C_MODE_CALLBACK /*!< I2C_transfer() does not block */ |
| } I2C_TransferMode; |
| |
| /*! |
| * @brief I2C callback function |
| * |
| * User-definable callback function prototype. The I2C driver will call this |
| * callback upon transfer completion, specifying the I2C handle for the |
| * transfer (as returned from I2C_open()), the pointer to the I2C_Transaction |
| * that just completed, and the return value of I2C_transfer(). Note that |
| * this return value will be the same as if the transfer were performed in |
| * blocking mode. |
| * |
| * @param I2C_Handle I2C_Handle |
| |
| * @param I2C_Transaction* Address of the I2C_Transaction |
| |
| * @param bool Result of the I2C transfer |
| */ |
| typedef void (*I2C_CallbackFxn)(I2C_Handle handle, I2C_Transaction *transaction, |
| bool transferStatus); |
| |
| /*! |
| * @brief I2C bitRate |
| * |
| * Specifies one of the standard I2C bus bit rates for I2C communications. |
| * The default is I2C_100kHz. |
| */ |
| typedef enum I2C_BitRate_ { |
| I2C_100kHz = 0, |
| I2C_400kHz = 1 |
| } I2C_BitRate; |
| |
| /*! |
| * @brief I2C Parameters |
| * |
| * I2C parameters are used with the I2C_open() call. Default values for |
| * these parameters are set using I2C_Params_init(). |
| * |
| * If I2C_TransferMode is set to I2C_MODE_BLOCKING, I2C_transfer() function |
| * calls will block thread execution until the transaction has completed. In |
| * this case, the transferCallbackFxn parameter will be ignored. |
| * |
| * If I2C_TransferMode is set to I2C_MODE_CALLBACK, I2C_transfer() will not |
| * block thread execution, but it will call the function specified by |
| * transferCallbackFxn upon transfer completion. Sequential calls to |
| * I2C_transfer() in I2C_MODE_CALLBACK will put the I2C_Transaction structures |
| * onto an internal queue that automatically starts queued transactions after |
| * the previous transaction has completed. This queuing occurs regardless of |
| * any error state from previous transactions. |
| * |
| * I2C_BitRate specifies the I2C bus rate used for I2C communications. |
| * |
| * @sa I2C_Params_init() |
| */ |
| typedef struct I2C_Params_ { |
| I2C_TransferMode transferMode; /*!< Blocking or Callback mode */ |
| I2C_CallbackFxn transferCallbackFxn; /*!< Callback function pointer */ |
| I2C_BitRate bitRate; /*!< I2C bus bit rate */ |
| void *custom; /*!< Custom argument used by driver |
| implementation */ |
| } I2C_Params; |
| |
| /*! |
| * @brief A function pointer to a driver-specific implementation of |
| * I2C_cancel(). |
| */ |
| typedef void (*I2C_CancelFxn) (I2C_Handle handle); |
| |
| /*! |
| * @brief A function pointer to a driver-specific implementation of |
| * I2C_close(). |
| */ |
| typedef void (*I2C_CloseFxn) (I2C_Handle handle); |
| |
| /*! |
| * @brief A function pointer to a driver-specific implementation of |
| * I2C_control(). |
| */ |
| typedef int_fast16_t (*I2C_ControlFxn) (I2C_Handle handle, uint_fast16_t cmd, |
| void *controlArg); |
| |
| /*! |
| * @brief A function pointer to a driver-specific implementation of |
| * I2C_init(). |
| */ |
| typedef void (*I2C_InitFxn) (I2C_Handle handle); |
| |
| /*! |
| * @brief A function pointer to a driver-specific implementation of |
| * I2C_open(). |
| */ |
| typedef I2C_Handle (*I2C_OpenFxn) (I2C_Handle handle, I2C_Params *params); |
| |
| /*! |
| * @brief A function pointer to a driver-specific implementation of |
| * I2C_transfer(). |
| */ |
| typedef bool (*I2C_TransferFxn) (I2C_Handle handle, |
| I2C_Transaction *transaction); |
| |
| /*! |
| * @brief The definition of an I2C function table that contains the |
| * required set of functions to control a specific I2C driver |
| * implementation. |
| */ |
| typedef struct I2C_FxnTable_ { |
| /*! Cancel all I2C data transfers */ |
| I2C_CancelFxn cancelFxn; |
| |
| /*! Close the specified peripheral */ |
| I2C_CloseFxn closeFxn; |
| |
| /*! Implementation-specific control function */ |
| I2C_ControlFxn controlFxn; |
| |
| /*! Initialize the given data object */ |
| I2C_InitFxn initFxn; |
| |
| /*! Open the specified peripheral */ |
| I2C_OpenFxn openFxn; |
| |
| /*! Initiate an I2C data transfer */ |
| I2C_TransferFxn transferFxn; |
| } I2C_FxnTable; |
| |
| /*! |
| * @brief I2C global configuration |
| * |
| * The I2C_Config structure contains a set of pointers used to characterize |
| * the I2C driver implementation. |
| * |
| * This structure needs to be defined before calling I2C_init() and it must |
| * not be changed thereafter. |
| * |
| * @sa I2C_init() |
| */ |
| typedef struct I2C_Config_ { |
| /*! Pointer to a table of driver-specific implementations of I2C APIs */ |
| I2C_FxnTable const *fxnTablePtr; |
| |
| /*! Pointer to a driver-specific data object */ |
| void *object; |
| |
| /*! Pointer to a driver-specific hardware attributes structure */ |
| void const *hwAttrs; |
| } I2C_Config; |
| |
| /*! |
| * @brief Cancel all I2C transfers |
| * |
| * This function will cancel asynchronous I2C_transfer() operations, and is |
| * applicable only for I2C_MODE_CALLBACK. An in progress transfer, as well |
| * as any queued transfers will be canceled. The individual callback functions |
| * for each transfer will be called from the context that I2C_cancel() is |
| * called. |
| * |
| * @pre I2C_Transfer() has been called. |
| * |
| * @param handle An I2C_Handle returned from I2C_open() |
| * |
| * @note Different I2C slave devices will behave differently when an |
| * in-progress transfer fails and needs to be canceled. The slave |
| * may need to be reset, or there may be other slave-specific |
| * steps that can be used to successfully resume communication. |
| * |
| * @sa I2C_transfer() |
| */ |
| extern void I2C_cancel(I2C_Handle handle); |
| |
| /*! |
| * @brief Close an I2C peripheral specified by an I2C_Handle |
| * |
| * @pre I2C_open() has been called. |
| * |
| * @param handle An I2C_Handle returned from I2C_open() |
| * |
| * @sa I2C_open() |
| */ |
| extern void I2C_close(I2C_Handle handle); |
| |
| /*! |
| * @brief Perform implementation-specific features on a given |
| * I2C_Handle. |
| * |
| * Commands for I2C_control() can originate from I2C.h or from implementation |
| * specific I2C*.h (I2CCC26XX.h_, I2CMSP432.h_, etc.) files. |
| * While commands from I2C.h are API portable across driver implementations, |
| * not all implementations may support all these commands. |
| * Conversely, commands from driver implementation specific I2C*.h files add |
| * unique driver capabilities but are not API portable across all I2C driver |
| * implementations. |
| * |
| * Commands supported by I2C.h follow a I2C_CMD_\<cmd\> naming |
| * convention.<br> |
| * Commands supported by I2C*.h follow a I2C*_CMD_\<cmd\> naming |
| * convention.<br> |
| * Each control command defines @b arg differently. The types of @b arg are |
| * documented with each command. |
| * |
| * See @ref I2C_CMD "I2C_control command codes" for command codes. |
| * |
| * See @ref I2C_STATUS "I2C_control return status codes" for status codes. |
| * |
| * @pre I2C_open() has to be called first. |
| * |
| * @param handle An I2C_Handle returned from I2C_open() |
| * |
| * @param cmd I2C.h or I2C*.h command. |
| * |
| * @param controlArg An optional R/W (read/write) command argument |
| * accompanied with cmd |
| * |
| * @return Implementation-specific return codes. Negative values indicate |
| * unsuccessful operations. |
| * |
| * @sa I2C_open() |
| */ |
| extern int_fast16_t I2C_control(I2C_Handle handle, uint_fast16_t cmd, |
| void *controlArg); |
| |
| /*! |
| * @brief Initializes the I2C module |
| * |
| * @pre The I2C_config structure must exist and be persistent before this |
| * function can be called. This function must also be called before |
| * any other I2C driver APIs. This function call does not modify any |
| * peripheral registers. |
| */ |
| extern void I2C_init(void); |
| |
| /*! |
| * @brief Initialize a given I2C peripheral as identified by an index value. |
| * The I2C_Params structure defines the operating mode, and any |
| * related settings. |
| * |
| * @pre The I2C controller has been initialized, via a previous call to |
| * I2C_init() |
| * |
| * @param index Logical peripheral number for the I2C indexed into |
| * the I2C_config table |
| * |
| * @param params Pointer to a parameter block. Default values will be |
| * used if NULL is specified for params. All the fields |
| * in this structure are are considered RO (read-only). |
| * |
| * @return An I2C_Handle on success, or NULL on an error, or if the peripheral |
| * is already opened. |
| * |
| * @sa I2C_init() |
| * @sa I2C_close() |
| */ |
| extern I2C_Handle I2C_open(uint_least8_t index, I2C_Params *params); |
| |
| /*! |
| * @brief Initialize an I2C_Params struct to its defaults |
| * |
| * @param params A pointer to I2C_Params structure for |
| * initialization |
| * |
| * Defaults values are: |
| * transferMode = I2C_MODE_BLOCKING |
| * transferCallbackFxn = NULL |
| * bitRate = I2C_100kHz |
| */ |
| extern void I2C_Params_init(I2C_Params *params); |
| |
| /*! |
| * @brief Perform an I2C transaction with an I2C slave peripheral. |
| * |
| * This function will perform an I2C transfer, as specified by an |
| * I2C_Transaction structure. |
| * |
| * An I2C transaction may write data to a peripheral, or read data from a |
| * peripheral, or both write and read data, in a single transaction. If there |
| * is any data to be written, it will always be sent before any data is read |
| * from the peripheral. |
| * |
| * The data written to the peripheral is preceded with the peripheral's 7-bit |
| * I2C slave address (with the Write bit set). |
| * After all the data has been transmitted, the driver will evaluate if any |
| * data needs to be read from the device. |
| * If yes, another START bit is sent, along with the same 7-bit I2C slave |
| * address (with the Read bit). After the specified number of bytes have been |
| * read, the transfer is ended with a NACK and a STOP bit. Otherwise, if |
| * no data is to be read, the transfer is concluded with a STOP bit. |
| * |
| * In I2C_MODE_BLOCKING, I2C_transfer() will block thread execution until the |
| * transaction completes. Therefore, this function must only be called from an |
| * appropriate thread context (e.g., Task context for the TI-RTOS kernel). |
| * |
| * In I2C_MODE_CALLBACK, the I2C_transfer() call does not block thread |
| * execution. Instead, a callback function (specified during I2C_open(), via |
| * the transferCallbackFxn field in the I2C_Params structure) is called when |
| * the transfer completes. Success or failure of the transaction is reported |
| * via the callback function's bool argument. If a transfer is already in |
| * progress, the new transaction is put on an internal queue. The driver |
| * services the queue in a first come first served basis. |
| * |
| * @param handle An I2C_Handle |
| * |
| * @param transaction A pointer to an I2C_Transaction. All of the fields |
| * within the transaction structure should be considered |
| * write only, unless otherwise noted in the driver |
| * implementation. |
| * |
| * @note The I2C_Transaction structure must persist unmodified until the |
| * corresponding call to I2C_transfer() has completed. |
| * |
| * @return In I2C_MODE_BLOCKING: true for a successful transfer; false for an |
| * error (for example, an I2C bus fault (NACK)). |
| * |
| * In I2C_MODE_CALLBACK: always true. The transferCallbackFxn's bool |
| * argument will be true to indicate success, and false to indicate |
| * an error. |
| * |
| * @sa I2C_open |
| */ |
| extern bool I2C_transfer(I2C_Handle handle, I2C_Transaction *transaction); |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif /* ti_drivers_I2C__include */ |