I2C.h
Go to the documentation of this file.
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 
290 #include <stdbool.h>
291 #include <stddef.h>
292 #include <stdint.h>
293 
294 #include <ti/drivers/dpl/HwiP.h>
295 #include <ti/drivers/dpl/SemaphoreP.h>
298 #ifdef __cplusplus
299 extern "C" {
300 #endif
301 
322 #define I2C_STATUS_RESERVED (-32)
323 
328 #define I2C_STATUS_QUEUED (1)
329 
333 #define I2C_STATUS_SUCCESS (0)
334 
338 #define I2C_STATUS_ERROR (-1)
339 
344 #define I2C_STATUS_UNDEFINEDCMD (-2)
345 
349 #define I2C_STATUS_TIMEOUT (-3)
350 
354 #define I2C_STATUS_CLOCK_TIMEOUT (-4)
355 
359 #define I2C_STATUS_ADDR_NACK (-5)
360 
364 #define I2C_STATUS_DATA_NACK (-6)
365 
369 #define I2C_STATUS_ARB_LOST (-7)
370 
374 #define I2C_STATUS_INCOMPLETE (-8)
375 
380 #define I2C_STATUS_BUS_BUSY (-9)
381 
385 #define I2C_STATUS_CANCEL (-10)
386 
394 #define I2C_STATUS_INVALID_TRANS (-11)
395 
400 #define I2C_WAIT_FOREVER (~(0U))
401 
405 typedef struct I2C_Config_ *I2C_Handle;
406 
416 typedef struct
417 {
422  void *writeBuf;
423 
438  size_t writeCount;
439 
444  void *readBuf;
445 
458  size_t readCount;
459 
470  void *arg;
471 
490  volatile int_fast16_t status;
491 
498  uint_least8_t slaveAddress;
499 
504  void *nextPtr;
506 
514 typedef enum
515 {
528 
543 
565 typedef void (*I2C_CallbackFxn)(I2C_Handle handle, I2C_Transaction *transaction, bool transferStatus);
566 
575 typedef enum
576 {
582 } I2C_BitRate;
583 
592 typedef struct
593 {
595  I2C_TransferMode transferMode;
596 
602 
608 
610  void *custom;
611 } I2C_Params;
612 
614 #define I2C_BASE_OBJECT \
615  /* I2C control variables */ \
616  I2C_TransferMode transferMode; /* Blocking or Callback mode */ \
617  I2C_CallbackFxn transferCallbackFxn; /* Callback function pointer */ \
618  I2C_Transaction *currentTransaction; /* Ptr to current I2C transaction */ \
619  \
620  /* I2C transaction pointers for I2C_MODE_CALLBACK */ \
621  I2C_Transaction *volatile headPtr; /* Head ptr for queued transactions */ \
622  I2C_Transaction *tailPtr; /* Tail ptr for queued transactions */ \
623  \
624  /* I2C RTOS objects */ \
625  HwiP_Struct hwi; /* Hwi object handle */ \
626  SemaphoreP_Struct mutex; /* Grants exclusive access to I2C */ \
627  SemaphoreP_Struct transferComplete; /* Signal I2C transfer complete */ \
628  \
629  /* Read and write variables */ \
630  const uint8_t *writeBuf; /* Internal inc. writeBuf index */ \
631  size_t writeCount; /* Internal dec. writeCounter */ \
632  uint8_t *readBuf; /* Internal inc. readBuf index */ \
633  size_t readCount; /* Internal dec. readCounter */ \
634  \
635  bool isOpen; /* Flag to show module is open */ \
636 
643 typedef struct
644 {
645  I2C_BASE_OBJECT
646 } I2C_Object;
650 #define I2C_BASE_HWATTRS \
651  \
652  uint32_t baseAddr; \
653  \
654  uint32_t intNum; \
655  \
668  uint32_t intPriority;
669 
675 typedef struct
676 {
677  I2C_BASE_HWATTRS
678 } I2C_HWAttrs;
688 typedef struct I2C_Config_
689 {
691  void *object;
692 
695  void const *hwAttrs;
696 } I2C_Config;
697 
698 extern const I2C_Config I2C_config[];
699 extern const uint_least8_t I2C_count;
700 
738 extern void I2C_cancel(I2C_Handle handle);
739 
747 extern void I2C_close(I2C_Handle handle);
748 
770 extern int_fast16_t I2C_control(I2C_Handle handle, uint_fast16_t cmd, void *controlArg);
771 
777 extern void I2C_init(void);
778 
794 extern I2C_Handle I2C_open(uint_least8_t index, I2C_Params *params);
795 
808 extern void I2C_Params_init(I2C_Params *params);
809 
832 extern int_fast16_t I2C_setClockTimeout(I2C_Handle handle, uint32_t timeout);
833 
866 extern bool I2C_transfer(I2C_Handle handle, I2C_Transaction *transaction);
867 
921 extern int_fast16_t I2C_transferTimeout(I2C_Handle handle, I2C_Transaction *transaction, uint32_t timeout);
922 
923 #ifdef __cplusplus
924 }
925 #endif
926 
927 #endif /* ti_drivers_I2C__include */
ADC_Params params
Definition: Driver_Init.h:11
void * writeBuf
Definition: I2C.h:422
void * arg
Definition: I2C.h:470
I2C_TransferMode transferMode
Definition: I2C.h:595
void * object
Definition: I2C.h:691
void * readBuf
Definition: I2C.h:444
void I2C_Params_init(I2C_Params *params)
Initialize an I2C_Params structure to its default values.
I2C_BitRate
Bit rate for an I2C driver instance specified in the I2C_Params.
Definition: I2C.h:575
struct I2C_Config_ * I2C_Handle
A handle that is returned from an I2C_open() call.
Definition: I2C.h:405
void const * hwAttrs
Definition: I2C.h:695
int_fast16_t I2C_control(I2C_Handle handle, uint_fast16_t cmd, void *controlArg)
Function performs implementation specific features on a driver instance.
Definition: I2C.h:527
const I2C_Config I2C_config[]
I2C_TransferMode
Return behavior of I2C_Transfer() specified in the I2C_Params.
Definition: I2C.h:514
I2C_CallbackFxn transferCallbackFxn
Definition: I2C.h:601
I2C_Handle I2C_open(uint_least8_t index, I2C_Params *params)
Open an I2C driver instance.
Definition: I2C.h:580
Definition: I2C.h:578
I2C_BitRate bitRate
Definition: I2C.h:607
void I2C_close(I2C_Handle handle)
Function to close an I2C driver instance.
int_fast16_t I2C_setClockTimeout(I2C_Handle handle, uint32_t timeout)
Set the I2C SCL clock timeout.
I2C parameters used with I2C_open().
Definition: I2C.h:592
struct I2C_Config_ I2C_Config
I2C driver&#39;s custom configuration structure.
Definition: I2C.h:581
uint_least8_t slaveAddress
Definition: I2C.h:498
Definition: I2C.h:579
void I2C_cancel(I2C_Handle handle)
Cancels all I2C transfers.
void * custom
Definition: I2C.h:610
I2C driver&#39;s custom configuration structure.
Definition: I2C.h:688
void(* I2C_CallbackFxn)(I2C_Handle handle, I2C_Transaction *transaction, bool transferStatus)
The definition of a callback function.
Definition: I2C.h:565
Definition: I2C.h:541
void I2C_init(void)
Function to initialize the I2C driver.
volatile int_fast16_t status
Definition: I2C.h:490
Defines a transaction to be used with I2C_transfer() or I2C_transferTimeout()
Definition: I2C.h:416
bool I2C_transfer(I2C_Handle handle, I2C_Transaction *transaction)
Perform an I2C transaction with an I2C slave peripheral.
size_t writeCount
Definition: I2C.h:438
const uint_least8_t I2C_count
Definition: I2C.h:577
size_t readCount
Definition: I2C.h:458
int_fast16_t I2C_transferTimeout(I2C_Handle handle, I2C_Transaction *transaction, uint32_t timeout)
Perform an I2C transaction with an I2C slave peripheral.
© Copyright 1995-2022, Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy policy | Terms of use | Terms of sale