I2CLPF3.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2022-2023, 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 I2CLPF3.h
34  *
35  * @brief I2C driver implementation for a Low Power F3 device I2C
36  * controller.
37  *
38  * # Driver Include #
39  * The I2C header file should be included in an application as follows:
40  * @code
41  * #include <ti/drivers/I2C.h>
42  * #include <ti/drivers/i2c/I2CLPF3.h>
43  * @endcode
44  *
45  * Refer to @ref I2C.h for a complete description of APIs.
46  *
47  * # Overview #
48  * The general I2C API is normally used in application code, e.g. I2C_open()
49  * is used instead of I2CLPF3_open(). The board file will define the device
50  * specific config, and casting in the general API will ensure that the correct
51  * device specific functions are called.
52  * This is also reflected in the example code in [Use Cases](@ref I2C_USE_CASES_LPF3).
53  *
54  * ## General Behavior #
55  * Before using the I2C in LPF3:
56  * - The I2C driver is initialized by calling I2C_init().
57  * - The I2C HW is configured and system dependencies are declared (e.g. IOs,
58  * power, etc.) by calling I2C_open().
59  * .
60  * The following is true for receive operation:
61  * - RX is enabled by calling I2C_transfer().
62  * The readCount of the ::I2C_Transaction must be set to a non-zero value.
63  * - If the I2C_transfer() succeeds, the I2C remains enabled.
64  * - The application must check the return value from I2C_transfer()
65  * to verify that the transfer succeeded.
66  * .
67  * The following apply for transmit operation:
68  * - TX is enabled by calling I2C_transfer().
69  * The writeCount of the ::I2C_Transaction must be set to a non-zero value.
70  * - If the I2C_transfer() succeeds, the I2C remains enabled.
71  * - The application must check the return value from I2C_transfer()
72  * to verify that the transfer succeeded.
73  * .
74  * After I2C operation has ended:
75  * - Release system dependencies for I2C by calling I2C_close().
76  *
77  * ### Known Issue #
78  * @warning The I2C will transmit a single data byte in the event that the
79  * I2C target address is not acknowledged (NACK'd). This is due to a known
80  * hardware bug.
81  *
82  * ## Error handling #
83  * If an error occurs during operation:
84  * - The I2C Controller transmits a stop bit and remains enabled.
85  * .
86  *
87  * ## Power Management #
88  * The I2CLPF3 driver sets a power constraint during transactions to keep
89  * the device out of standby; so when all tasks are blocked, the device will
90  * enter idle mode instead of standby. When the transactions have finished,
91  * the power constraint to prohibit standby is released.
92  * The following statements are valid:
93  * - After I2C_open() call: I2C is enabled, there are no active I2C
94  * transactions, the device can enter standby.
95  * - After I2C_transfer() call: active I2C transactions exist, the device
96  * might enter idle, but not standby.
97  * - When I2C_transfer() completes, either after success or error, I2C
98  * remains enabled, and the device can enter standby.
99  * - After I2C_close() call: I2C is disabled
100  * - If the device goes into idle during a transaction, the state of
101  * SDA is undefined in the time between the transaction completing and
102  * the device waking up. SCL will go low until the device wakes up and
103  * starts another transaction or releases the bus. If this is a problem
104  * for another device on the I2C bus, you can set a power constraint for
105  * #PowerLPF3_DISALLOW_IDLE before the transaction and release it
106  * when the transaction completes.
107  *
108  * ## Supported Functions ##
109  * | Generic API Function | API Function | Description |
110  * |--------------------- |------------------------- |---------------------------------------------------|
111  * | I2C_init() | I2CLPF3_init() | Initialize I2C driver |
112  * | I2C_open() | I2CLPF3_open() | Initialize I2C HW and set system dependencies |
113  * | I2C_close() | I2CLPF3_close() | Disable I2C HW and release system dependencies |
114  * | I2C_transfer() | I2CLPF3_transfer() | Start I2C transfer |
115  *
116  * @note All calls should go through the generic API.
117  *
118  * ## Supported Bit Rates ##
119  * - #I2C_100kHz
120  * - #I2C_400kHz
121  *
122  * ## Unsupported Functionality #
123  * The LPF3 I2C driver currently does not support:
124  * - Multi-controller mode
125  * - I2C target mode
126  *
127  * ## Use Cases @anchor I2C_USE_CASES_LPF3 ##
128  * ### Basic Receive #
129  * Receive 10 bytes over I2C in ::I2C_MODE_BLOCKING.
130  * @code
131  * // Locals
132  * I2C_Handle handle;
133  * I2C_Params params;
134  * I2C_Transaction i2cTrans;
135  * uint8_t rxBuf[32]; // Receive buffer
136  * uint8_t txBuf[32]; // Transmit buffer
137  *
138  * // Configure I2C parameters.
139  * I2C_Params_init(&params);
140  *
141  * // Initialize I2C transaction structure
142  * i2cTrans.writeCount = 0;
143  * i2cTrans.writeBuf = txBuf;
144  * i2cTrans.readCount = 10;
145  * i2cTrans.readBuf = rxBuf;
146  * i2cTrans.targetAddress = 0x3C;
147  *
148  * // Open I2C
149  * handle = I2C_open(CONFIG_I2C, &params);
150  *
151  * // Do I2C transfer receive
152  * I2C_transfer(handle, &i2cTrans);
153  * @endcode
154  *
155  * ### Basic Transmit #
156  * Transmit 16 bytes over I2C in ::I2C_MODE_CALLBACK.
157  * @code
158  * uint8_t rxBuffer[32]; // Receive buffer
159  * uint8_t txBuffer[32]; // Transmit buffer
160  * bool transferDone = false;
161  *
162  * static void transferCallback(I2C_Handle handle, I2C_Transaction *transac, bool result)
163  * {
164  * // Set length bytes
165  * if (result) {
166  * transferDone = true;
167  * } else {
168  * // Transaction failed, act accordingly...
169  * .
170  * .
171  * }
172  * }
173  *
174  * static void taskFxn(uintptr_t a0, uintptr_t a1)
175  * {
176  * // Locals
177  * I2C_Handle handle;
178  * I2C_Params params;
179  * I2C_Transaction i2cTrans;
180  *
181  * // Configure I2C parameters.
182  * I2C_Params_init(&params);
183  * params.transferMode = I2C_MODE_CALLBACK;
184  * params.transferCallbackFxn = transferCallback;
185  *
186  * // Prepare data to send, send 0x00, 0x01, 0x02, ...0xFF, 0x00, 0x01...
187  * for(uint32_t i = 0; i < numTxBytes; i++)
188  * txBuffer[i] = (uint8_t) i;
189  *
190  * // Initialize I2C transaction structure
191  * i2cTrans.writeCount = 16;
192  * i2cTrans.writeBuf = txBuffer;
193  * i2cTrans.readCount = 0;
194  * i2cTrans.readBuf = rxBuffer;
195  * i2cTrans.targetAddress = 0x3C;
196  *
197  * // Open I2C
198  * handle = I2C_open(CONFIG_I2C, &params);
199  *
200  * // Do I2C transfer (in callback mode)
201  * I2C_transfer(handle, &i2cTrans);
202  *
203  * // Do other stuff while I2C is handling the transfer
204  * .
205  * .
206  *
207  * // Do something if I2C transfer is finished
208  * if(transferDone) {
209  * .
210  * .
211  * }
212  *
213  * // Continue...
214  * .
215  * .
216  * }
217  * @endcode
218  *
219  * ### Chained Transactions #
220  * Transmit 10 bytes and then 32 bytes over I2C in ::I2C_MODE_CALLBACK.
221  * @code
222  * uint8_t rxBuffer[32]; // Receive buffer
223  * uint8_t txBuffer[32]; // Transmit buffer
224  * uint8_t rxBuffer2[64]; // Receive buffer 2
225  * uint8_t txBuffer2[64]; // Transmit buffer 2
226  * bool transferDone = false;
227  *
228  * static void writeCallbackDefault(I2C_Handle handle, I2C_Transaction *transac, bool result)
229  * {
230  * // Set length bytes
231  * if (result) {
232  * transferDone = true;
233  * } else {
234  * // Transaction failed, act accordingly...
235  * .
236  * .
237  * }
238  * }
239  *
240  * static void taskFxn(uintptr_t a0, uintptr_t a1)
241  * {
242  * // Locals
243  * I2C_Handle handle;
244  * I2C_Params params;
245  * I2C_Transaction i2cTrans;
246  * I2C_Transaction i2cTrans2;
247  *
248  * // Configure I2C parameters.
249  * I2C_Params_init(&params);
250  * params.transferMode = I2C_MODE_CALLBACK;
251  * params.transferCallbackFxn = writeCallbackDefault;
252  *
253  * // Prepare data to send, send 0x00, 0x01, 0x02, ...0xFF, 0x00, 0x01...
254  * for(uint32_t i = 0; i < numTxBytes; i++)
255  * txBuffer[i] = (uint8_t) i;
256  *
257  * // Initialize first I2C transaction structure
258  * i2cTrans.writeCount = 10;
259  * i2cTrans.writeBuf = txBuffer;
260  * i2cTrans.readCount = 0;
261  * i2cTrans.readBuf = rxBuffer;
262  * i2cTrans.targetAddress = 0x3C;
263  *
264  * // Second transaction
265  * i2cTrans2.writeCount = 32;
266  * i2cTrans2.writeBuf = txBuffer2;
267  * i2cTrans2.readCount = 0;
268  * i2cTrans2.readBuf = rxBuffer2;
269  * i2cTrans2.targetAddress = 0x2E;
270  *
271  * // Open I2C
272  * handle = I2C_open(CONFIG_I2C, &params);
273  *
274  * // Do chained I2C transfers (in callback mode).
275  * I2C_transfer(handle, &i2cTrans);
276  * I2C_transfer(handle, &i2cTrans2);
277  *
278  * // Do other stuff while I2C is handling the transfers
279  * .
280  * .
281  *
282  * // Do something if I2C transfers are finished
283  * if(transferDone) {
284  * .
285  * .
286  * }
287  *
288  * // Continue...
289  * .
290  * .
291  * }
292  * @endcode
293  *
294  * # Instrumentation #
295  * The I2C driver interface produces log statements if instrumentation is
296  * enabled.
297  *
298  * Diagnostics Mask | Log details |
299  * ---------------- | ----------- |
300  * Diags_USER1 | basic I2C operations performed |
301  * Diags_USER2 | detailed I2C operations performed |
302  *
303  ******************************************************************************
304  */
305 
306 #ifndef ti_drivers_i2c_I2CLPF3__include
307 #define ti_drivers_i2c_I2CLPF3__include
308 
309 #include <stdint.h>
310 #include <stdbool.h>
311 
312 #include <ti/drivers/I2C.h>
313 #include <ti/drivers/Power.h>
314 
315 #include <ti/drivers/dpl/SwiP.h>
316 
317 #ifdef __cplusplus
318 extern "C" {
319 #endif
320 
342 typedef struct
343 {
344  uint8_t pinSDA;
345  uint8_t pinSCL;
347 
395 typedef struct
396 {
397  I2C_BASE_HWATTRS
398 
399  /* I2C peripheral's Power driver ID */
400  unsigned long powerMngrId;
401 
402  /*
403  * I2C Swi priority.
404  * The higher the number, the higher the priority.
405  * The minimum is 0 and the maximum is 15 by default.
406  * The maximum can be reduced to save RAM by adding or modifying
407  * Swi.numPriorities in the kernel configuration file.
408  */
409  uint32_t swiPriority;
410  /* SDA pin index and mux */
411  uint8_t sdaPin;
412  uint8_t sdaPinMux;
413  /* SCL pin index and mux */
414  uint8_t sclPin;
415  uint8_t sclPinMux;
417 
423 typedef struct
424 {
425  I2C_BASE_OBJECT
426 
427  /* Swi object */
428  SwiP_Struct swi;
429 
430  /* Bitrate of the I2C module */
431  uint32_t bitRate;
432 
433  /* Pin indexes. We need to cache these because we might have custom pins */
434  uint8_t sdaPin;
435  uint8_t sclPin;
436 
437  /* I2C power notification */
438  void *i2cPostFxn;
441 
442 #ifdef __cplusplus
443 }
444 #endif
445 
446 #endif /* ti_drivers_i2c_I2CLPF3__include */
Power_NotifyObj i2cPostObj
Definition: I2CLPF3.h:439
uint8_t sclPin
Definition: I2CLPF3.h:414
uint8_t sdaPin
Definition: I2CLPF3.h:411
uint8_t sclPin
Definition: I2CLPF3.h:435
uint8_t pinSCL
Definition: I2CLPF3.h:345
I2C_BASE_OBJECT SwiP_Struct swi
Definition: I2CLPF3.h:428
uint8_t sclPinMux
Definition: I2CLPF3.h:415
Power Manager.
uint8_t sdaPinMux
Definition: I2CLPF3.h:412
I2C_BASE_HWATTRS unsigned long powerMngrId
Definition: I2CLPF3.h:400
uint32_t bitRate
Definition: I2CLPF3.h:431
I2CLPF3 Object.
Definition: I2CLPF3.h:423
uint8_t sdaPin
Definition: I2CLPF3.h:434
Power notify object structure.
Definition: Power.h:445
uint32_t swiPriority
Definition: I2CLPF3.h:409
void * i2cPostFxn
Definition: I2CLPF3.h:438
I2CLPF3 Hardware attributes.
Definition: I2CLPF3.h:395
uint8_t pinSDA
Definition: I2CLPF3.h:344
I2CLPF3 Pin Configuration.
Definition: I2CLPF3.h:342
Inter-Integrated Circuit (I2C) Driver.
© Copyright 1995-2023, Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy policy | Terms of use | Terms of sale