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  * I2C_Params i2cParams;
75  *
76  * i2cHandle = I2C_open(Board_I2C0, NULL);
77  *
78  * if (i2cHandle == NULL) {
79  * // Error opening I2C
80  * while (1);
81  * }
82  * @endcode
83  *
84  * ## I2C Driver Configuration ##
85  *
86  * In order to use the I2C APIs, the application is required to provide
87  * device-specific I2C configuration in the Board.c file. The I2C driver
88  * interface defines a configuration data structure, #I2C_Config.
89  *
90  * The application must declare an array of #I2C_Config elements, named
91  * \p I2C_config[]. Each element of \p I2C_config[] is populated with
92  * pointers to a device specific I2C driver implementation's function
93  * table, driver object, and hardware attributes. The hardware attributes
94  * define properties such as the I2C peripheral's base address and
95  * pins. Each element in \p I2C_config[] corresponds to an I2C instance,
96  * and none of the elements should have \p NULL pointers.
97  *
98  * The I2C configuration is device dependent. You will need to check the
99  * device specific I2C driver documentation. There you will find a
100  * description of the I2C hardware attributes.
101  *
102  * ## Initializing the I2C Driver ##
103  *
104  * I2C_init() must be called before any other I2C APIs. This function
105  * calls the device specific implementation's I2C initialization function
106  * for each element of \p NVS_config[].
107  *
108  * ## Opening the I2C Driver ##
109  *
110  * After initializing the I2C driver by calling I2C_init(), the application
111  * can open an I2C instance by calling I2C_open(). This function
112  * takes an index into the \p I2C_config[] array and an #I2C_Params structure.
113  * The #I2C_Handle returned from the I2C_open() is then associated with that
114  * index into the \p I2C_config[] array.
115  *
116  * \note Each I2C index can only be opened exclusively. Calling I2C_open()
117  * multiple times with the same index will result in an error. The index can
118  * be re-used if I2C_close() is called first.
119  *
120  * This example shows opening an I2C driver instance in callback mode
121  * with a bit rate of 400kbps.
122  *
123  * @code
124  * I2C_Handle i2cHandle;
125  * I2C_Params i2cParams;
126  *
127  * I2C_Params_init(&i2cParams);
128  *
129  * i2cParams.transferMode = I2C_MODE_CALLBACK;
130  * i2cParams.transferCallbackFxn = myCallbackFunction;
131  * i2cParams.bitRate = I2C_400kHz;
132  *
133  * handle = I2C_open(Board_I2C0, &i2cParams);
134  *
135  * if (i2cHandle == NULL) {
136  * // Error opening I2C
137  * while (1);
138  * }
139  * @endcode
140  *
141  * ## Transferring data ##
142  *
143  * An I2C data transfer is performed using the I2C_transfer() function. Three
144  * types of transactions are supported: write, read, and write + read. The
145  * details of each transaction are specified with an #I2C_Transaction
146  * structure. Each transfer is completed before another transfer is initiated.
147  *
148  * For write + read transactions, the specified data is first written to the
149  * peripheral, then a repeated start is sent by the driver, which initiates
150  * the read operation. This type of transfer is useful if an I2C peripheral
151  * has a pointer register that needs to be adjusted prior to reading from
152  * the referenced data register.
153  *
154  * The below example shows sending three bytes of data to a slave peripheral
155  * at address 0x50, in blocking mode:
156  *
157  * @code
158  * uint8_t writeBuffer[3];
159  * I2C_Transaction i2cTransaction;
160  *
161  * i2cTransaction.slaveAddress = 0x50;
162  * i2cTransaction.writeBuf = writeBuffer;
163  * i2cTransaction.writeCount = 3;
164  * i2cTransaction.readBuf = NULL;
165  * i2cTransaction.readCount = 0;
166  *
167  * status = I2C_transfer(i2cHandle, &i2cTransaction);
168  *
169  * if (status == False) {
170  * // Unsuccessful I2C transfer
171  * }
172  * @endcode
173  *
174  * The next example shows reading five bytes of data from the I2C
175  * peripheral, in blocking mode:
176  *
177  * @code
178  * uint8_t readBuffer[5];
179  * I2C_Transaction i2cTransaction;
180  *
181  * i2cTransaction.slaveAddress = 0x50;
182  * i2cTransaction.writeBuf = NULL;
183  * i2cTransaction.writeCount = 0;
184  * i2cTransaction.readBuf = readBuffer;
185  * i2cTransaction.readCount = 5;
186  *
187  * status = I2C_transfer(i2cHandle, &i2cTransaction);
188  *
189  * if (status == False) {
190  * // Unsuccessful I2C transfer
191  * }
192  * @endcode
193  *
194  * This example shows writing two bytes and reading four bytes in a
195  * single transaction.
196  *
197  * @code
198  * uint8_t readBuffer[4];
199  * uint8_t writeBuffer[2];
200  * I2C_Transaction i2cTransaction;
201  *
202  * i2cTransaction.slaveAddress = 0x50;
203  * i2cTransaction.writeBuf = writeBuffer;
204  * i2cTransaction.writeCount = 2;
205  * i2cTransaction.readBuf = readBuffer;
206  * i2cTransaction.readCount = 4;
207  *
208  * status = I2C_transfer(i2cHandle, &i2cTransaction);
209  *
210  * if (status == False) {
211  * // Unsuccessful I2C transfer
212  * }
213  * @endcode
214  *
215  * This final example shows usage of asynchronous callback mode, with queuing
216  * of multiple transactions. Because multiple transactions are simultaneously
217  * queued, separate #I2C_Transaction structures must be used.
218  *
219  * \note #I2C_Transaction structures cannot be \b re-used until the previous
220  * transaction has completed.
221  *
222  * First, the callback function specified by #I2C_Params.transferCallbackFxn
223  * is created. In this example, the #I2C_Transaction will contain a custom
224  * application argument. This argument will be a semaphore handle. The
225  * #I2C_Transaction.arg will point to the semaphore handle. When the callback
226  * function is called, the #I2C_Transaction.arg is checked for \p NULL. If
227  * this value is not \p NULL, then it can be assumed the \p arg is pointing
228  * to a valid semaphore handle. The semaphore handle is then used to call
229  * \p sem_post(). Hypothetically, this can be used to signal transaction
230  * completion to the task(s) that queued the transaction(s).
231  *
232  * @code
233  * void callbackFxn(I2C_Handle handle, I2C_Transaction *msg, bool transfer)
234  * {
235  *
236  * // Check for a semaphore handle
237  * if (msg->arg != NULL) {
238  *
239  * // Perform a semaphore post
240  * sem_post((sem_t *) (msg->arg));
241  * }
242  * }
243  * @endcode
244  *
245  * Snippets of the task code that initiates the transactions are shown below.
246  * Note the use of multiple #I2C_Transaction structures. The handle of the
247  * semaphore to be posted is specified via \p i2cTransaction2.arg.
248  * I2C_transfer() is called three times to initiate each transaction.
249  * Since callback mode is used, these functions return immediately. After
250  * the transactions have been queued, other work can be done. Eventually,
251  * \p sem_wait() is called causing the task to block until the transaction
252  * completes. When the transaction completes, the application's callback
253  * callback function, \p callbackFxn will be called. Once \p callbackFxn
254  * above posts the semaphore the task will be unblocked and can resume
255  * execution.
256  *
257  * @code
258  * void taskfxn(arg0, arg1)
259  * {
260  *
261  * I2C_Transaction i2cTransaction0;
262  * I2C_Transaction i2cTransaction1;
263  * I2C_Transaction i2cTransaction2;
264  *
265  * // ...
266  *
267  * i2cTransaction0.arg = NULL;
268  * i2cTransaction1.arg = NULL;
269  * i2cTransaction2.arg = semaphoreHandle;
270  *
271  * // ...
272  *
273  * I2C_transfer(i2c, &i2cTransaction0);
274  * I2C_transfer(i2c, &i2cTransaction1);
275  * I2C_transfer(i2c, &i2cTransaction2);
276  *
277  * // ...
278  *
279  * sem_wait(semaphoreHandle);
280  * }
281  * @endcode
282  *
283  * # Implementation #
284  *
285  * This top-level I2C module serves as the main interface for RTOS
286  * applications. Its purpose is to redirect the module's APIs to specific
287  * peripheral implementations which are specified using a pointer to an
288  * #I2C_FxnTable.
289  *
290  * The I2C driver interface module is joined (at link time) to an
291  * array of #I2C_Config data structures named \p I2C_config.
292  * \p I2C_config is typically defined in the Board.c file used for the
293  * application. If there are multiple instances of I2C peripherals on the
294  * device, there will typically be multiple #I2C_Config structures defined in
295  * the board file in the form of an array. Each entry in \p I2C_config
296  * contains a:
297  * - #I2C_FxnTable pointer to a set of functions that implement an I2C
298  * peripheral.
299  * - (\p void *) data object that is associated with the #I2C_FxnTable
300  * - (\p void *) hardware attributes that are associated to the #I2C_FxnTable
301  *
302  *
303  ******************************************************************************
304  */
305 
306 #ifndef ti_drivers_I2C__include
307 #define ti_drivers_I2C__include
308 
309 #ifdef __cplusplus
310 extern "C" {
311 #endif
312 
313 #include <stdbool.h>
314 #include <stddef.h>
315 #include <stdint.h>
316 
334 #define I2C_CMD_RESERVED (32)
335 
348 #define I2C_STATUS_RESERVED (-32)
349 
363 #define I2C_STATUS_SUCCESS (0)
364 
371 #define I2C_STATUS_ERROR (-1)
372 
380 #define I2C_STATUS_UNDEFINEDCMD (-2)
381 
391 /* Add I2C_CMD_<commands> here */
392 
400 typedef struct I2C_Config_ *I2C_Handle;
401 
411 typedef struct I2C_Transaction_ {
412  void *writeBuf;
414  size_t writeCount;
416  void *readBuf;
417  size_t readCount;
419  uint_least8_t slaveAddress;
421  void *arg;
425  void *nextPtr;
429 
440 typedef enum I2C_TransferMode_ {
462 
475 typedef void (*I2C_CallbackFxn)(I2C_Handle handle, I2C_Transaction *transaction,
476  bool transferStatus);
477 
483 typedef enum I2C_BitRate_ {
484 
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:417
This structure defines the I2C slave address, pointers to write and read buffers, and their associate...
Definition: I2C.h:411
I2C_BitRate_
Specifies one of the standard I2C bus bit rates for I2C communication. You must check that the device...
Definition: I2C.h:483
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:425
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:400
size_t writeCount
Definition: I2C.h:414
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:485
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:416
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:440
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:488
Definition: I2C.h:487
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:446
void * writeBuf
Definition: I2C.h:412
struct I2C_Config_ I2C_Config
I2C global configuration.
Definition: I2C.h:486
void I2C_cancel(I2C_Handle handle)
Cancel all I2C transfers.
void * arg
Definition: I2C.h:421
uint_least8_t slaveAddress
Definition: I2C.h:419
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:475
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:441
Copyright 2018, Texas Instruments Incorporated