I2C.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-2018, 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-Intergrated Circuit driver interface.
35  *
36  * To use the I2C driver, ensure that the correct driver library for your
37  * device is linked in and include this header file as follows:
38  * @code
39  * #include <ti/drivers/I2C.h>
40  * @endcode
41  *
42  * This module serves as the main interface for applications using an
43  * underlying I2C peripheral. Its purpose is to redirect the I2C APIs to
44  * device specific driver implementations which are specified using a pointer
45  * to a #I2C_FxnTable.
46  *
47  * # Overview #
48  *
49  * This section assumes that you have prior knowledge about the I2C protocol.
50  * For the full I2C-bus specification and user manual, view the \b UM10204
51  * document available online.
52  *
53  * This I2C driver is designed to operate as an I2C master. This driver
54  * does not support I2C slave mode. This driver assumes it is the only I2C
55  * master on the I2C bus. Using the I2C APIs, you can transmit and recieve
56  * data over an I2C bus. The I2C-bus specification does not define how data
57  * is to be formatted or handled. This allows for flexible implementations
58  * across different peripheral vendors. As a result, this driver only
59  * performs the exchange of data between the master and slave(s). The
60  * application is responsible for manipulating and interpretting the data.
61  *
62  * # Thread Safety #
63  *
64  * This driver has been designed to operate in a Real-Time Operating System
65  * (RTOS) environment. This driver protects data transactions with operating
66  * system primitives supplied by the underlying RTOS.
67  *
68  * # Usage #
69  *
70  * The following code example opens an I2C instance.
71  *
72  * @code
73  * I2C_Handle i2cHandle;
74  *
75  * i2cHandle = I2C_open(Board_I2C0, NULL);
76  *
77  * if (i2cHandle == NULL) {
78  * // Error opening I2C
79  * while (1);
80  * }
81  * @endcode
82  *
83  * ## I2C Driver Configuration ##
84  *
85  * In order to use the I2C APIs, the application is required to provide
86  * device-specific I2C configuration in the Board.c file. The I2C driver
87  * interface defines a configuration data structure, #I2C_Config.
88  *
89  * The application must declare an array of #I2C_Config elements, named
90  * \p I2C_config[]. Each element of \p I2C_config[] is populated with
91  * pointers to a device specific I2C driver implementation's function
92  * table, driver object, and hardware attributes. The hardware attributes
93  * define properties such as the I2C peripheral's base address and
94  * pins. Each element in \p I2C_config[] corresponds to an I2C instance,
95  * and none of the elements should have \p NULL pointers.
96  *
97  * The I2C configuration is device dependent. You will need to check the
98  * device specific I2C driver documentation. There you will find a
99  * description of the I2C hardware attributes.
100  *
101  * ## Initializing the I2C Driver ##
102  *
103  * I2C_init() must be called before any other I2C APIs. This function
104  * calls the device specific implementation's I2C initialization function
105  * for each element of \p NVS_config[].
106  *
107  * ## Opening the I2C Driver ##
108  *
109  * After initializing the I2C driver by calling I2C_init(), the application
110  * can open an I2C instance by calling I2C_open(). This function
111  * takes an index into the \p I2C_config[] array and an #I2C_Params structure.
112  * The #I2C_Handle returned from the I2C_open() is then associated with that
113  * index into the \p I2C_config[] array.
114  *
115  * \note Each I2C index can only be opened exclusively. Calling I2C_open()
116  * multiple times with the same index will result in an error. The index can
117  * be re-used if I2C_close() is called first.
118  *
119  * This example shows opening an I2C driver instance in callback mode
120  * with a bit rate of 400kbps.
121  *
122  * @code
123  * I2C_Handle i2cHandle;
124  * I2C_Params i2cParams;
125  *
126  * I2C_Params_init(&i2cParams);
127  *
128  * i2cParams.transferMode = I2C_MODE_CALLBACK;
129  * i2cParams.transferCallbackFxn = myCallbackFunction;
130  * i2cParams.bitRate = I2C_400kHz;
131  *
132  * i2cHandle = I2C_open(Board_I2C0, &i2cParams);
133  *
134  * if (i2cHandle == NULL) {
135  * // Error opening I2C
136  * while (1);
137  * }
138  * @endcode
139  *
140  * ## Transferring data ##
141  *
142  * An I2C data transfer is performed using the I2C_transfer() function. Three
143  * types of transactions are supported: write, read, and write + read. The
144  * details of each transaction are specified with an #I2C_Transaction
145  * structure. Each transfer is completed before another transfer is initiated.
146  *
147  * For write + read transactions, the specified data is first written to the
148  * peripheral, then a repeated start is sent by the driver, which initiates
149  * the read operation. This type of transfer is useful if an I2C peripheral
150  * has a pointer register that needs to be adjusted prior to reading from
151  * the referenced data register.
152  *
153  * The below example shows sending three bytes of data to a slave peripheral
154  * at address 0x50, in blocking mode:
155  *
156  * @code
157  * uint8_t writeBuffer[3];
158  * I2C_Transaction i2cTransaction;
159  *
160  * i2cTransaction.slaveAddress = 0x50;
161  * i2cTransaction.writeBuf = writeBuffer;
162  * i2cTransaction.writeCount = 3;
163  * i2cTransaction.readBuf = NULL;
164  * i2cTransaction.readCount = 0;
165  *
166  * status = I2C_transfer(i2cHandle, &i2cTransaction);
167  *
168  * if (status == False) {
169  * // Unsuccessful I2C transfer
170  * }
171  * @endcode
172  *
173  * The next example shows reading five bytes of data from the I2C
174  * peripheral, in blocking mode:
175  *
176  * @code
177  * uint8_t readBuffer[5];
178  * I2C_Transaction i2cTransaction;
179  *
180  * i2cTransaction.slaveAddress = 0x50;
181  * i2cTransaction.writeBuf = NULL;
182  * i2cTransaction.writeCount = 0;
183  * i2cTransaction.readBuf = readBuffer;
184  * i2cTransaction.readCount = 5;
185  *
186  * status = I2C_transfer(i2cHandle, &i2cTransaction);
187  *
188  * if (status == False) {
189  * // Unsuccessful I2C transfer
190  * }
191  * @endcode
192  *
193  * This example shows writing two bytes and reading four bytes in a
194  * single transaction.
195  *
196  * @code
197  * uint8_t readBuffer[4];
198  * uint8_t writeBuffer[2];
199  * I2C_Transaction i2cTransaction;
200  *
201  * i2cTransaction.slaveAddress = 0x50;
202  * i2cTransaction.writeBuf = writeBuffer;
203  * i2cTransaction.writeCount = 2;
204  * i2cTransaction.readBuf = readBuffer;
205  * i2cTransaction.readCount = 4;
206  *
207  * status = I2C_transfer(i2cHandle, &i2cTransaction);
208  *
209  * if (status == False) {
210  * // Unsuccessful I2C transfer
211  * }
212  * @endcode
213  *
214  * This final example shows usage of asynchronous callback mode, with queuing
215  * of multiple transactions. Because multiple transactions are simultaneously
216  * queued, separate #I2C_Transaction structures must be used.
217  *
218  * \note #I2C_Transaction structures cannot be \b re-used until the previous
219  * transaction has completed.
220  *
221  * First, the callback function specified by #I2C_Params.transferCallbackFxn
222  * is created. In this example, the #I2C_Transaction will contain a custom
223  * application argument. This argument will be a semaphore handle. The
224  * #I2C_Transaction.arg will point to the semaphore handle. When the callback
225  * function is called, the #I2C_Transaction.arg is checked for \p NULL. If
226  * this value is not \p NULL, then it can be assumed the \p arg is pointing
227  * to a valid semaphore handle. The semaphore handle is then used to call
228  * \p sem_post(). Hypothetically, this can be used to signal transaction
229  * completion to the task(s) that queued the transaction(s).
230  *
231  * @code
232  * void callbackFxn(I2C_Handle handle, I2C_Transaction *msg, bool transfer)
233  * {
234  *
235  * // Check for a semaphore handle
236  * if (msg->arg != NULL) {
237  *
238  * // Perform a semaphore post
239  * sem_post((sem_t *) (msg->arg));
240  * }
241  * }
242  * @endcode
243  *
244  * Snippets of the task code that initiates the transactions are shown below.
245  * Note the use of multiple #I2C_Transaction structures. The handle of the
246  * semaphore to be posted is specified via \p i2cTransaction2.arg.
247  * I2C_transfer() is called three times to initiate each transaction.
248  * Since callback mode is used, these functions return immediately. After
249  * the transactions have been queued, other work can be done. Eventually,
250  * \p sem_wait() is called causing the task to block until the transaction
251  * completes. When the transaction completes, the application's callback
252  * callback function, \p callbackFxn will be called. Once \p callbackFxn
253  * above posts the semaphore the task will be unblocked and can resume
254  * execution.
255  *
256  * @code
257  * void taskfxn(arg0, arg1)
258  * {
259  *
260  * I2C_Transaction i2cTransaction0;
261  * I2C_Transaction i2cTransaction1;
262  * I2C_Transaction i2cTransaction2;
263  *
264  * // ...
265  *
266  * i2cTransaction0.arg = NULL;
267  * i2cTransaction1.arg = NULL;
268  * i2cTransaction2.arg = semaphoreHandle;
269  *
270  * // ...
271  *
272  * I2C_transfer(i2c, &i2cTransaction0);
273  * I2C_transfer(i2c, &i2cTransaction1);
274  * I2C_transfer(i2c, &i2cTransaction2);
275  *
276  * // ...
277  *
278  * sem_wait(semaphoreHandle);
279  * }
280  * @endcode
281  *
282  * # Implementation #
283  *
284  * This top-level I2C module serves as the main interface for RTOS
285  * applications. Its purpose is to redirect the module's APIs to specific
286  * peripheral implementations which are specified using a pointer to an
287  * #I2C_FxnTable.
288  *
289  * The I2C driver interface module is joined (at link time) to an
290  * array of #I2C_Config data structures named \p I2C_config.
291  * \p I2C_config is typically defined in the Board.c file used for the
292  * application. If there are multiple instances of I2C peripherals on the
293  * device, there will typically be multiple #I2C_Config structures defined in
294  * the board file in the form of an array. Each entry in \p I2C_config
295  * contains a:
296  * - #I2C_FxnTable pointer to a set of functions that implement an I2C
297  * peripheral.
298  * - (\p void *) data object that is associated with the #I2C_FxnTable
299  * - (\p void *) hardware attributes that are associated to the #I2C_FxnTable
300  *
301  *
302  ******************************************************************************
303  */
304 
305 #ifndef ti_drivers_I2C__include
306 #define ti_drivers_I2C__include
307 
308 #ifdef __cplusplus
309 extern "C" {
310 #endif
311 
312 #include <stdbool.h>
313 #include <stddef.h>
314 #include <stdint.h>
315 
333 #define I2C_CMD_RESERVED (32)
334 
347 #define I2C_STATUS_RESERVED (-32)
348 
362 #define I2C_STATUS_SUCCESS (0)
363 
370 #define I2C_STATUS_ERROR (-1)
371 
379 #define I2C_STATUS_UNDEFINEDCMD (-2)
380 
390 /* Add I2C_CMD_<commands> here */
391 
399 typedef struct I2C_Config_ *I2C_Handle;
400 
410 typedef struct I2C_Transaction_ {
411  void *writeBuf;
413  size_t writeCount;
415  void *readBuf;
416  size_t readCount;
418  uint_least8_t slaveAddress;
420  void *arg;
424  void *nextPtr;
428 
439 typedef enum I2C_TransferMode_ {
461 
474 typedef void (*I2C_CallbackFxn)(I2C_Handle handle, I2C_Transaction *transaction,
475  bool transferStatus);
476 
482 typedef enum I2C_BitRate_ {
483 
489 } I2C_BitRate;
490 
499 typedef struct I2C_Params_ {
500  I2C_TransferMode transferMode;
507  void *custom;
509 } I2C_Params;
510 
515 typedef void (*I2C_CancelFxn) (I2C_Handle handle);
516 
521 typedef void (*I2C_CloseFxn) (I2C_Handle handle);
522 
527 typedef int_fast16_t (*I2C_ControlFxn) (I2C_Handle handle, uint_fast16_t cmd,
528  void *controlArg);
529 
534 typedef void (*I2C_InitFxn) (I2C_Handle handle);
535 
540 typedef I2C_Handle (*I2C_OpenFxn) (I2C_Handle handle, I2C_Params *params);
541 
546 typedef bool (*I2C_TransferFxn) (I2C_Handle handle,
547  I2C_Transaction *transaction);
548 
554 typedef struct I2C_FxnTable_ {
557 
560 
563 
566 
569 
572 } I2C_FxnTable;
573 
585 typedef struct I2C_Config_ {
588 
590  void *object;
591 
593  void const *hwAttrs;
594 } I2C_Config;
595 
616 extern void I2C_cancel(I2C_Handle handle);
617 
627 extern void I2C_close(I2C_Handle handle);
628 
666 extern int_fast16_t I2C_control(I2C_Handle handle, uint_fast16_t cmd,
667  void *controlArg);
668 
677 extern void I2C_init(void);
678 
700 extern I2C_Handle I2C_open(uint_least8_t index, I2C_Params *params);
701 
714 extern void I2C_Params_init(I2C_Params *params);
715 
767 extern bool I2C_transfer(I2C_Handle handle, I2C_Transaction *transaction);
768 
769 #ifdef __cplusplus
770 }
771 #endif
772 
773 #endif /* ti_drivers_I2C__include */
I2C Parameters.
Definition: I2C.h:499
size_t readCount
Definition: I2C.h:416
This structure defines the I2C slave address, pointers to write and read buffers, and their associate...
Definition: I2C.h:410
I2C_BitRate_
Specifies one of the standard I2C bus bit rates for I2C communication. You must check that the device...
Definition: I2C.h:482
void * object
Definition: I2C.h:590
I2C_OpenFxn openFxn
Definition: I2C.h:568
void I2C_Params_init(I2C_Params *params)
Initialize an I2C_Params structure to its default values.
void(* I2C_CloseFxn)(I2C_Handle handle)
A function pointer to a driver-specific implementation of I2C_close().
Definition: I2C.h:521
void * nextPtr
Definition: I2C.h:424
I2C_TransferMode transferMode
Definition: I2C.h:500
void(* I2C_InitFxn)(I2C_Handle handle)
A function pointer to a driver-specific implementation of I2C_init().
Definition: I2C.h:534
struct I2C_Transaction_ I2C_Transaction
This structure defines the I2C slave address, pointers to write and read buffers, and their associate...
struct I2C_Config_ * I2C_Handle
A handle that is returned from an I2C_open() call.
Definition: I2C.h:399
size_t writeCount
Definition: I2C.h:413
void const * hwAttrs
Definition: I2C.h:593
int_fast16_t I2C_control(I2C_Handle handle, uint_fast16_t cmd, void *controlArg)
Perform implementation-specific features on a given I2C_Handle.
Definition: I2C.h:484
I2C_CloseFxn closeFxn
Definition: I2C.h:559
void(* I2C_CancelFxn)(I2C_Handle handle)
A function pointer to a driver-specific implementation of I2C_cancel().
Definition: I2C.h:515
struct I2C_Params_ I2C_Params
I2C Parameters.
void * readBuf
Definition: I2C.h:415
I2C_InitFxn initFxn
Definition: I2C.h:565
I2C_CancelFxn cancelFxn
Definition: I2C.h:556
I2C_TransferMode_
This I2C driver supports two transfer modes of operation: blocking and callback. The transfer mode is...
Definition: I2C.h:439
Definition: I2C.h:488
enum I2C_TransferMode_ I2C_TransferMode
This I2C driver supports two transfer modes of operation: blocking and callback. The transfer mode is...
I2C_CallbackFxn transferCallbackFxn
Definition: I2C.h:502
bool(* I2C_TransferFxn)(I2C_Handle handle, I2C_Transaction *transaction)
A function pointer to a driver-specific implementation of I2C_transfer().
Definition: I2C.h:546
I2C_Handle I2C_open(uint_least8_t index, I2C_Params *params)
Initialize a given I2C peripheral as identified by an index value. The I2C_Params structure defines t...
Definition: I2C.h:487
Definition: I2C.h:486
The definition of an I2C function table that contains the required set of functions to control a spec...
Definition: I2C.h:554
struct I2C_FxnTable_ I2C_FxnTable
The definition of an I2C function table that contains the required set of functions to control a spec...
enum I2C_BitRate_ I2C_BitRate
Specifies one of the standard I2C bus bit rates for I2C communication. You must check that the device...
void I2C_close(I2C_Handle handle)
Close an I2C peripheral specified by an I2C_Handle.
I2C_BitRate bitRate
Definition: I2C.h:505
Definition: I2C.h:445
void * writeBuf
Definition: I2C.h:411
struct I2C_Config_ I2C_Config
I2C global configuration.
Definition: I2C.h:485
void I2C_cancel(I2C_Handle handle)
Cancel all I2C transfers.
void * arg
Definition: I2C.h:420
uint_least8_t slaveAddress
Definition: I2C.h:418
I2C global configuration.
Definition: I2C.h:585
void(* I2C_CallbackFxn)(I2C_Handle handle, I2C_Transaction *transaction, bool transferStatus)
I2C callback function prototype. The application is responsible for declaring a callback function whe...
Definition: I2C.h:474
void I2C_init(void)
Initializes the I2C module.
I2C_FxnTable const * fxnTablePtr
Definition: I2C.h:587
void * custom
Definition: I2C.h:507
bool I2C_transfer(I2C_Handle handle, I2C_Transaction *transaction)
Perform an I2C transaction with an I2C slave peripheral.
int_fast16_t(* I2C_ControlFxn)(I2C_Handle handle, uint_fast16_t cmd, void *controlArg)
A function pointer to a driver-specific implementation of I2C_control().
Definition: I2C.h:527
I2C_ControlFxn controlFxn
Definition: I2C.h:562
I2C_Handle(* I2C_OpenFxn)(I2C_Handle handle, I2C_Params *params)
A function pointer to a driver-specific implementation of I2C_open().
Definition: I2C.h:540
I2C_TransferFxn transferFxn
Definition: I2C.h:571
Definition: I2C.h:440
Copyright 2018, Texas Instruments Incorporated