1e41f4b71Sopenharmony_ci# I2C
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci
4e41f4b71Sopenharmony_ci## Overview
5e41f4b71Sopenharmony_ci
6e41f4b71Sopenharmony_ci### Function
7e41f4b71Sopenharmony_ci
8e41f4b71Sopenharmony_ciThe Inter-Integrated Circuit (I2C) is a simple, bidirectional, and synchronous serial bus that uses merely two wires. It is widely used in short-distance communication due to simple connection and low cost.
9e41f4b71Sopenharmony_ci
10e41f4b71Sopenharmony_ci### Working Principles
11e41f4b71Sopenharmony_ci
12e41f4b71Sopenharmony_ciIn I2C communication, one controller communicates with one or more devices through the serial data line (SDA) and serial clock line (SCL), as shown in the figure below.
13e41f4b71Sopenharmony_ci
14e41f4b71Sopenharmony_ciI2C data transfer must begin with a **START** condition and end with a **STOP** condition. Data is transmitted byte-by-byte from the most significant bit to the least significant bit.
15e41f4b71Sopenharmony_ci
16e41f4b71Sopenharmony_ciEach I2C node is recognized by a unique address and can serve as either a controller or a device. When the controller needs to communicate with a device, it writes the device address to the bus through broadcast. A device matching this address sends a response to set up a data transfer channel.
17e41f4b71Sopenharmony_ci
18e41f4b71Sopenharmony_ciThe I2C module provides a set of APIs for I2C data transfer, including:
19e41f4b71Sopenharmony_ci- Opening or closing an I2C controller
20e41f4b71Sopenharmony_ci- Performing custom transfer via a message array
21e41f4b71Sopenharmony_ci
22e41f4b71Sopenharmony_ci    **Figure 1** I2C physical connection
23e41f4b71Sopenharmony_ci
24e41f4b71Sopenharmony_ci    ![](figures/physical-connection-diagram-for-i2c.png "physical-connection-diagram-for-i2c")
25e41f4b71Sopenharmony_ci
26e41f4b71Sopenharmony_ci## Usage Guidelines
27e41f4b71Sopenharmony_ci
28e41f4b71Sopenharmony_ci### When to Use
29e41f4b71Sopenharmony_ci
30e41f4b71Sopenharmony_ciThe I2C is used in communication with the sensors, executors, and input/output devices that support the I2C protocol.
31e41f4b71Sopenharmony_ci
32e41f4b71Sopenharmony_ci### Available APIs
33e41f4b71Sopenharmony_ci
34e41f4b71Sopenharmony_ciThe following table describes the APIs provided by the I2C module. For more information about the APIs, see **//drivers/hdf_core/framework/include/platform/i2c_if.h**.
35e41f4b71Sopenharmony_ci
36e41f4b71Sopenharmony_ci**Table 1** I2C driver APIs
37e41f4b71Sopenharmony_ci
38e41f4b71Sopenharmony_ci|  API | Description|
39e41f4b71Sopenharmony_ci| -------- | -------- |
40e41f4b71Sopenharmony_ci| DevHandle I2cOpen(int16_t number) | Opens an I2C controller.|
41e41f4b71Sopenharmony_ci| void I2cClose(DevHandle handle) | Closes an I2C controller.|
42e41f4b71Sopenharmony_ci| int32_t I2cTransfer(DevHandle handle, struct I2cMsg \*msgs, int16_t count) | Transfers data.|
43e41f4b71Sopenharmony_ci
44e41f4b71Sopenharmony_ci### How to Use
45e41f4b71Sopenharmony_ci
46e41f4b71Sopenharmony_ciThe following figure illustrates how to use I2C APIs.
47e41f4b71Sopenharmony_ci
48e41f4b71Sopenharmony_ci**Figure 2** Process of using I2C APIs
49e41f4b71Sopenharmony_ci
50e41f4b71Sopenharmony_ci![](figures/using-I2C-process.png "process-of-using-an-i2c-device")
51e41f4b71Sopenharmony_ci
52e41f4b71Sopenharmony_ci
53e41f4b71Sopenharmony_ci#### Opening an I2C Controller
54e41f4b71Sopenharmony_ci
55e41f4b71Sopenharmony_ciCall **I2cOpen()** to open an I2C controller.
56e41f4b71Sopenharmony_ci
57e41f4b71Sopenharmony_ci```c
58e41f4b71Sopenharmony_ciDevHandle I2cOpen(int16_t number);
59e41f4b71Sopenharmony_ci```
60e41f4b71Sopenharmony_ci
61e41f4b71Sopenharmony_ci  **Table 2** Description of I2cOpen
62e41f4b71Sopenharmony_ci
63e41f4b71Sopenharmony_ci| **Parameter**| **Description**|
64e41f4b71Sopenharmony_ci| -------- | -------- |
65e41f4b71Sopenharmony_ci| number | I2C controller number.|
66e41f4b71Sopenharmony_ci| Return Value| **Description**|
67e41f4b71Sopenharmony_ci| NULL | The operation fails.|
68e41f4b71Sopenharmony_ci| Device handle| The operation is successful. The handle of the I2C controller opened is returned.|
69e41f4b71Sopenharmony_ci
70e41f4b71Sopenharmony_ciExample: Open controller 3 of the eight I2C controllers (numbered 0 and 7) in the system.
71e41f4b71Sopenharmony_ci
72e41f4b71Sopenharmony_ci```c
73e41f4b71Sopenharmony_ciDevHandle i2cHandle = NULL; /* I2C controller handle. */
74e41f4b71Sopenharmony_ci
75e41f4b71Sopenharmony_ci/* Open I2C controller 3. */
76e41f4b71Sopenharmony_cii2cHandle = I2cOpen(3);
77e41f4b71Sopenharmony_ciif (i2cHandle == NULL) {
78e41f4b71Sopenharmony_ci    HDF_LOGE("I2cOpen: failed\n");
79e41f4b71Sopenharmony_ci    return;
80e41f4b71Sopenharmony_ci}
81e41f4b71Sopenharmony_ci```
82e41f4b71Sopenharmony_ci
83e41f4b71Sopenharmony_ci
84e41f4b71Sopenharmony_ci#### Performing I2C Communication
85e41f4b71Sopenharmony_ci
86e41f4b71Sopenharmony_ciCall **I2cTransfer()** to transfer data.
87e41f4b71Sopenharmony_ci
88e41f4b71Sopenharmony_ci```c
89e41f4b71Sopenharmony_ciint32_t I2cTransfer(DevHandle handle, struct I2cMsg \*msgs, int16_t count);
90e41f4b71Sopenharmony_ci```
91e41f4b71Sopenharmony_ci
92e41f4b71Sopenharmony_ci  **Table 3** Description of I2cTransfer
93e41f4b71Sopenharmony_ci
94e41f4b71Sopenharmony_ci| **Parameter**| **Description**|
95e41f4b71Sopenharmony_ci| -------- | -------- |
96e41f4b71Sopenharmony_ci| handle | Handle of the I2C controller.|
97e41f4b71Sopenharmony_ci| msgs | Pointer to the message array to transfer.|
98e41f4b71Sopenharmony_ci| count | Number of messages in the message array to transfer.|
99e41f4b71Sopenharmony_ci| Return Value| **Description**|
100e41f4b71Sopenharmony_ci| Positive integer| The operation is successful. The number of messages that are successfully transferred is returned.|
101e41f4b71Sopenharmony_ci| Negative value| The operation fails.|
102e41f4b71Sopenharmony_ci
103e41f4b71Sopenharmony_ciThe I2C message type is defined by **I2cMsg**. Each message structure indicates a read or write operation. A message array specifies multiple read and write operations to perform. 
104e41f4b71Sopenharmony_ci
105e41f4b71Sopenharmony_ciExample of read and write operations:
106e41f4b71Sopenharmony_ci
107e41f4b71Sopenharmony_ci
108e41f4b71Sopenharmony_ci```c
109e41f4b71Sopenharmony_ciint32_t ret;
110e41f4b71Sopenharmony_ciuint8_t wbuff[2] = { 0x12, 0x13 };
111e41f4b71Sopenharmony_ciuint8_t rbuff[2] = { 0 };
112e41f4b71Sopenharmony_cistruct I2cMsg msgs[2];        /* Custom message array to transfer. */
113e41f4b71Sopenharmony_cimsgs[0].buf = wbuff;          /* Data to write. */
114e41f4b71Sopenharmony_cimsgs[0].len = 2;              /* The length of the data to write is 2. */
115e41f4b71Sopenharmony_cimsgs[0].addr = 0x5A;          /* The address of the device to write the data is 0x5A. */
116e41f4b71Sopenharmony_cimsgs[0].flags = 0;            /* The flag 0 indicates a write operation. */
117e41f4b71Sopenharmony_cimsgs[1].buf = rbuff;          /* Data to read. */
118e41f4b71Sopenharmony_cimsgs[1].len = 2;              /* The length of the data to read is 2. */
119e41f4b71Sopenharmony_cimsgs[1].addr = 0x5A;          /* The address of the device to read is 0x5A. */
120e41f4b71Sopenharmony_cimsgs[1].flags = I2C_FLAG_READ /* I2C_FLAG_READ is set. */
121e41f4b71Sopenharmony_ci/* Transfer two messages. */
122e41f4b71Sopenharmony_ciret = I2cTransfer(i2cHandle, msgs, 2);
123e41f4b71Sopenharmony_ciif (ret != 2) {
124e41f4b71Sopenharmony_ci    HDF_LOGE("I2cTransfer: failed, ret %d\n", ret);
125e41f4b71Sopenharmony_ci    return;
126e41f4b71Sopenharmony_ci}
127e41f4b71Sopenharmony_ci```
128e41f4b71Sopenharmony_ci
129e41f4b71Sopenharmony_ci> ![icon-caution.gif](../public_sys-resources/icon-caution.gif) **CAUTION**<br/>
130e41f4b71Sopenharmony_ci> - The device address in the **I2cMsg** structure does not contain the read/write flag bit. The read/write information is passed by the read/write control bit in **flags**.
131e41f4b71Sopenharmony_ci>
132e41f4b71Sopenharmony_ci> - The I2C controller determines the maximum number of messages to be transferred at a time and the maximum length of each message to transfer.
133e41f4b71Sopenharmony_ci>
134e41f4b71Sopenharmony_ci> - The **I2cTransfer** function may cause the system to sleep and therefore cannot be called in the interrupt context.
135e41f4b71Sopenharmony_ci
136e41f4b71Sopenharmony_ci
137e41f4b71Sopenharmony_ci#### Closing an I2C Controller
138e41f4b71Sopenharmony_ci
139e41f4b71Sopenharmony_ciCall **I2cClose()** to close the I2C controller after the communication is complete.
140e41f4b71Sopenharmony_ci
141e41f4b71Sopenharmony_ci```c
142e41f4b71Sopenharmony_civoid I2cClose(DevHandle handle); 
143e41f4b71Sopenharmony_ci```
144e41f4b71Sopenharmony_ci
145e41f4b71Sopenharmony_ci  **Table 4** Description of I2cClose
146e41f4b71Sopenharmony_ci
147e41f4b71Sopenharmony_ci| Parameter| Description|
148e41f4b71Sopenharmony_ci| -------- | -------- |
149e41f4b71Sopenharmony_ci| handle | Handle of the I2C controller to close.|
150e41f4b71Sopenharmony_ci
151e41f4b71Sopenharmony_ciExample:
152e41f4b71Sopenharmony_ci
153e41f4b71Sopenharmony_ci```c
154e41f4b71Sopenharmony_ciI2cClose(i2cHandle); /* Close an I2C controller. */
155e41f4b71Sopenharmony_ci```
156e41f4b71Sopenharmony_ci
157e41f4b71Sopenharmony_ci
158e41f4b71Sopenharmony_ci### Example
159e41f4b71Sopenharmony_ci
160e41f4b71Sopenharmony_ciThe following example describes how to use I2C APIs to implement simple read/write operations on TouchPad from a Hi3516D V300 development board. 
161e41f4b71Sopenharmony_ci
162e41f4b71Sopenharmony_ciThe basic hardware information is as follows:
163e41f4b71Sopenharmony_ci
164e41f4b71Sopenharmony_ci- SoC: Hi3516D V300
165e41f4b71Sopenharmony_ci
166e41f4b71Sopenharmony_ci- Touch IC: The I2C address is 0x38, and the bit width of touch IC internal register is 1 byte.
167e41f4b71Sopenharmony_ci
168e41f4b71Sopenharmony_ci- Hardware connection: The TouchPad is connected to I2C controller 3. The reset pin of the touch IC is GPIO 3.
169e41f4b71Sopenharmony_ci
170e41f4b71Sopenharmony_ciIn this example, reset the touch IC (the development board supplies power to the touch IC by default after being powered on) and perform read/write operations on the internal register to test whether the I2C channel is functioning.
171e41f4b71Sopenharmony_ci
172e41f4b71Sopenharmony_ci> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br>
173e41f4b71Sopenharmony_ci> This example focuses on access to the I2C device and verifies the I2C channel, rather than the specific data read from or written to the device register and the result caused by the read and write operations on the register.
174e41f4b71Sopenharmony_ci
175e41f4b71Sopenharmony_ciThe sample code is as follows:
176e41f4b71Sopenharmony_ci
177e41f4b71Sopenharmony_ci```c
178e41f4b71Sopenharmony_ci#include "i2c_if.h"          /* Header file of I2C APIs. */
179e41f4b71Sopenharmony_ci#include "gpio_if.h"         /* Header file of GPIO APIs. */
180e41f4b71Sopenharmony_ci#include "hdf_log.h"         /* Header file of log APIs. */
181e41f4b71Sopenharmony_ci#include "osal_io.h"         /* Header file of I/O read and write APIs. */
182e41f4b71Sopenharmony_ci#include "osal_time.h"       /* Header file of delay and sleep APIs. */
183e41f4b71Sopenharmony_ci
184e41f4b71Sopenharmony_ci/* Define a TP device structure to store I2C and GPIO hardware information. */
185e41f4b71Sopenharmony_cistruct TpI2cDevice {
186e41f4b71Sopenharmony_ci     uint16_t rstGpio;            /* Reset pin. */
187e41f4b71Sopenharmony_ci    uint16_t busId;               /* I2C bus number. */
188e41f4b71Sopenharmony_ci    uint16_t addr;                /* I2C device address. */
189e41f4b71Sopenharmony_ci    uint16_t regLen;              /* Register bit width. */
190e41f4b71Sopenharmony_ci    DevHandle i2cHandle;          /* I2C controller handle. */
191e41f4b71Sopenharmony_ci};
192e41f4b71Sopenharmony_ci
193e41f4b71Sopenharmony_ci/* I2C pin I/O configuration. For details, see the SoC register manual. */
194e41f4b71Sopenharmony_ci#define I2C3_DATA_REG_ADDR 0x112f008c  /* Address of the SDA pin configuration register of I2C controller 3. */
195e41f4b71Sopenharmony_ci#define I2C3_CLK_REG_ADDR 0x112f0090   /* Address of the SCL pin configuration register of I2C controller 3. */
196e41f4b71Sopenharmony_ci#define I2C_REG_CFG 0x5f1              /* Configuration values of SDA and SCL pins of I2C controller 3. */
197e41f4b71Sopenharmony_ci
198e41f4b71Sopenharmony_cistatic void TpSocIoCfg(void)
199e41f4b71Sopenharmony_ci{
200e41f4b71Sopenharmony_ci    /* Set the I/O function of the two pins corresponding to I2C controller 3 to I2C. */
201e41f4b71Sopenharmony_ci    OSAL_WRITEL(I2C_REG_CFG, IO_DEVICE_ADDR(I2C3_DATA_REG_ADDR));
202e41f4b71Sopenharmony_ci    OSAL_WRITEL(I2C_REG_CFG, IO_DEVICE_ADDR(I2C3_CLK_REG_ADDR));
203e41f4b71Sopenharmony_ci}
204e41f4b71Sopenharmony_ci
205e41f4b71Sopenharmony_ci/* Initialize the reset pin of the TP. Pull up the pin for 20 ms, pull down the pin for 50 ms, and then pull up the pin for 20 ms to complete the reset. */
206e41f4b71Sopenharmony_cistatic int32_t TestCaseGpioInit(struct TpI2cDevice *tpDevice)
207e41f4b71Sopenharmony_ci{
208e41f4b71Sopenharmony_ci    int32_t ret;
209e41f4b71Sopenharmony_ci
210e41f4b71Sopenharmony_ci    /* Set the output direction for the reset pin. */
211e41f4b71Sopenharmony_ci    ret = GpioSetDir(tpDevice->rstGpio, GPIO_DIR_OUT);
212e41f4b71Sopenharmony_ci    if (ret != HDF_SUCCESS) {
213e41f4b71Sopenharmony_ci        HDF_LOGE("%s: set rst dir fail!:%d", __func__, ret);
214e41f4b71Sopenharmony_ci        return ret;
215e41f4b71Sopenharmony_ci    }
216e41f4b71Sopenharmony_ci
217e41f4b71Sopenharmony_ci    ret = GpioWrite(tpDevice->rstGpio, GPIO_VAL_HIGH);
218e41f4b71Sopenharmony_ci    if (ret != HDF_SUCCESS) {
219e41f4b71Sopenharmony_ci        HDF_LOGE("%s: set rst hight fail!:%d", __func__, ret);
220e41f4b71Sopenharmony_ci        return ret;
221e41f4b71Sopenharmony_ci    }
222e41f4b71Sopenharmony_ci    OsalMSleep(20);
223e41f4b71Sopenharmony_ci
224e41f4b71Sopenharmony_ci    ret = GpioWrite(tpDevice->rstGpio, GPIO_VAL_LOW);
225e41f4b71Sopenharmony_ci    if (ret != HDF_SUCCESS) {
226e41f4b71Sopenharmony_ci        HDF_LOGE("%s: set rst low fail!:%d", __func__, ret);
227e41f4b71Sopenharmony_ci        return ret;
228e41f4b71Sopenharmony_ci    }
229e41f4b71Sopenharmony_ci    OsalMSleep(50);
230e41f4b71Sopenharmony_ci
231e41f4b71Sopenharmony_ci    ret = GpioWrite(tpDevice->rstGpio, GPIO_VAL_HIGH);
232e41f4b71Sopenharmony_ci    if (ret != HDF_SUCCESS) {
233e41f4b71Sopenharmony_ci        HDF_LOGE("%s: set rst high fail!:%d", __func__, ret);
234e41f4b71Sopenharmony_ci        return ret;
235e41f4b71Sopenharmony_ci    }
236e41f4b71Sopenharmony_ci    OsalMSleep(20);
237e41f4b71Sopenharmony_ci
238e41f4b71Sopenharmony_ci    return HDF_SUCCESS;
239e41f4b71Sopenharmony_ci}
240e41f4b71Sopenharmony_ci
241e41f4b71Sopenharmony_ci/* Use I2cTransfer to encapsulate a register read/write auxiliary function. Use flag to indicate the read or write operation. */
242e41f4b71Sopenharmony_cistatic int TpI2cReadWrite(struct TpI2cDevice *tpDevice, unsigned int regAddr,
243e41f4b71Sopenharmony_ci    unsigned char *regData, unsigned int dataLen, uint8_t flag)
244e41f4b71Sopenharmony_ci{
245e41f4b71Sopenharmony_ci    int index = 0;
246e41f4b71Sopenharmony_ci    unsigned char regBuf[4] = {0};
247e41f4b71Sopenharmony_ci    struct I2cMsg msgs[2] = {0};
248e41f4b71Sopenharmony_ci
249e41f4b71Sopenharmony_ci    /* Perform length adaptation for the single- or dual-byte register. */
250e41f4b71Sopenharmony_ci    if (tpDevice->regLen == 1) { 
251e41f4b71Sopenharmony_ci        regBuf[index++] = regAddr & 0xFF;
252e41f4b71Sopenharmony_ci    } else {
253e41f4b71Sopenharmony_ci        regBuf[index++] = (regAddr >> 8) & 0xFF;
254e41f4b71Sopenharmony_ci        regBuf[index++] = regAddr & 0xFF;
255e41f4b71Sopenharmony_ci    }
256e41f4b71Sopenharmony_ci
257e41f4b71Sopenharmony_ci    /* Fill in the I2cMsg message structure. */
258e41f4b71Sopenharmony_ci    msgs[0].addr = tpDevice->addr;
259e41f4b71Sopenharmony_ci    msgs[0].flags = 0; /* The flag 0 indicates a write operation. */
260e41f4b71Sopenharmony_ci    msgs[0].len = tpDevice->regLen;
261e41f4b71Sopenharmony_ci    msgs[0].buf = regBuf;
262e41f4b71Sopenharmony_ci
263e41f4b71Sopenharmony_ci    msgs[1].addr = tpDevice->addr;
264e41f4b71Sopenharmony_ci    msgs[1].flags = (flag == 1)? I2C_FLAG_READ: 0; /* Add the read flag. */
265e41f4b71Sopenharmony_ci    msgs[1].len = dataLen;
266e41f4b71Sopenharmony_ci    msgs[1].buf = regData;
267e41f4b71Sopenharmony_ci
268e41f4b71Sopenharmony_ci    if (I2cTransfer(tpDevice->i2cHandle, msgs, 2) != 2) {
269e41f4b71Sopenharmony_ci        HDF_LOGE("%s: i2c read err", __func__);
270e41f4b71Sopenharmony_ci        return HDF_FAILURE;
271e41f4b71Sopenharmony_ci    }
272e41f4b71Sopenharmony_ci    return HDF_SUCCESS;
273e41f4b71Sopenharmony_ci}
274e41f4b71Sopenharmony_ci
275e41f4b71Sopenharmony_ci/* TP register read function. */
276e41f4b71Sopenharmony_cistatic inline int TpI2cReadReg(struct TpI2cDevice *tpDevice, unsigned int regAddr,
277e41f4b71Sopenharmony_ci    unsigned char *regData, unsigned int dataLen)
278e41f4b71Sopenharmony_ci{
279e41f4b71Sopenharmony_ci    return TpI2cReadWrite(tpDevice, regAddr, regData, dataLen, 1);
280e41f4b71Sopenharmony_ci}
281e41f4b71Sopenharmony_ci
282e41f4b71Sopenharmony_ci/* TP register write function. */
283e41f4b71Sopenharmony_cistatic inline int TpI2cWriteReg(struct TpI2cDevice *tpDevice, unsigned int regAddr,
284e41f4b71Sopenharmony_ci    unsigned char *regData, unsigned int dataLen)
285e41f4b71Sopenharmony_ci{
286e41f4b71Sopenharmony_ci    return TpI2cReadWrite(tpDevice, regAddr, regData, dataLen, 0);
287e41f4b71Sopenharmony_ci}
288e41f4b71Sopenharmony_ci
289e41f4b71Sopenharmony_ci/* Main entry of I2C */
290e41f4b71Sopenharmony_cistatic int32_t TestCaseI2c(void)
291e41f4b71Sopenharmony_ci{
292e41f4b71Sopenharmony_ci    int32_t i;
293e41f4b71Sopenharmony_ci    int32_t ret;
294e41f4b71Sopenharmony_ci    unsigned char bufWrite[7] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xA, 0xB, 0xC };
295e41f4b71Sopenharmony_ci    unsigned char bufRead[7] = {0};
296e41f4b71Sopenharmony_ci    static struct TpI2cDevice tpDevice;
297e41f4b71Sopenharmony_ci
298e41f4b71Sopenharmony_ci    /* Configuration of I/O pin functions. */
299e41f4b71Sopenharmony_ci    TpSocIoCfg();
300e41f4b71Sopenharmony_ci
301e41f4b71Sopenharmony_ci    /* Initialize TP device information. */
302e41f4b71Sopenharmony_ci    tpDevice.rstGpio = 3;
303e41f4b71Sopenharmony_ci    tpDevice.busId = 3;
304e41f4b71Sopenharmony_ci    tpDevice.addr = 0x38;
305e41f4b71Sopenharmony_ci    tpDevice.regLen = 1;
306e41f4b71Sopenharmony_ci    tpDevice.i2cHandle = NULL;
307e41f4b71Sopenharmony_ci
308e41f4b71Sopenharmony_ci     /* Initialize the GPIO pin. */
309e41f4b71Sopenharmony_ci    ret = TestCaseGpioInit(&tpDevice);
310e41f4b71Sopenharmony_ci    if (ret != HDF_SUCCESS) {
311e41f4b71Sopenharmony_ci        HDF_LOGE("%s: gpio init fail!:%d", __func__, ret);
312e41f4b71Sopenharmony_ci        return ret;
313e41f4b71Sopenharmony_ci    }
314e41f4b71Sopenharmony_ci
315e41f4b71Sopenharmony_ci    /* Open an I2C controller. */
316e41f4b71Sopenharmony_ci    tpDevice.i2cHandle = I2cOpen(tpDevice.busId);
317e41f4b71Sopenharmony_ci    if (tpDevice.i2cHandle == NULL) {
318e41f4b71Sopenharmony_ci        HDF_LOGE("%s: Open I2c:%u fail!", __func__, tpDevice.busId);
319e41f4b71Sopenharmony_ci        return -1;
320e41f4b71Sopenharmony_ci    }
321e41f4b71Sopenharmony_ci
322e41f4b71Sopenharmony_ci    /* Continuously write 7-byte data to register 0xD5 of TP-IC. */
323e41f4b71Sopenharmony_ci    ret = TpI2cWriteReg(&tpDevice, 0xD5, bufWrite, 7);
324e41f4b71Sopenharmony_ci    if (ret != HDF_SUCCESS) {
325e41f4b71Sopenharmony_ci        HDF_LOGE("%s: tp i2c write reg fail!:%d", __func__, ret);
326e41f4b71Sopenharmony_ci        I2cClose(tpDevice.i2cHandle);
327e41f4b71Sopenharmony_ci        return -1;
328e41f4b71Sopenharmony_ci    }
329e41f4b71Sopenharmony_ci    OsalMSleep(10);
330e41f4b71Sopenharmony_ci
331e41f4b71Sopenharmony_ci    /* Continuously read 7-byte data from register 0xD5 of TP-IC. */
332e41f4b71Sopenharmony_ci    ret = TpI2cReadReg(&tpDevice, 0xD5, bufRead, 7);
333e41f4b71Sopenharmony_ci    if (ret != HDF_SUCCESS) {
334e41f4b71Sopenharmony_ci        HDF_LOGE("%s: tp i2c read reg fail!:%d", __func__, ret);
335e41f4b71Sopenharmony_ci        I2cClose(tpDevice.i2cHandle);
336e41f4b71Sopenharmony_ci        return -1;
337e41f4b71Sopenharmony_ci    }
338e41f4b71Sopenharmony_ci
339e41f4b71Sopenharmony_ci    HDF_LOGE("%s: tp i2c write&read reg success!", __func__);
340e41f4b71Sopenharmony_ci    for (i = 0; i < 7; i++) {
341e41f4b71Sopenharmony_ci        HDF_LOGE("%s: bufRead[%d] = 0x%x", __func__, i, bufRead[i]);
342e41f4b71Sopenharmony_ci    }
343e41f4b71Sopenharmony_ci
344e41f4b71Sopenharmony_ci    /* Close the I2C controller. */
345e41f4b71Sopenharmony_ci    I2cClose(tpDevice.i2cHandle);
346e41f4b71Sopenharmony_ci    return ret;
347e41f4b71Sopenharmony_ci}
348e41f4b71Sopenharmony_ci```
349