1 /*
2 * Copyright (c) 2022 FuZhou Lockzhiner Electronic Co., Ltd. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef LZ_HARDWARE_I2C_H
17 #define LZ_HARDWARE_I2C_H
18
19 #include "lz_hardware.h"
20 #include "stdlib.h"
21 #include "string.h"
22
23 typedef struct _LzI2cMsg {
24 unsigned short addr; /* slave address */
25 unsigned short flags;
26 #define I2C_M_RD 0x0001 /* read data, from slave to master */
27 /* I2C_M_RD is guaranteed to be 0x0001! */
28 #define I2C_M_TEN 0x0010 /* this is a ten bit chip address */
29 #define I2C_M_DMA_SAFE 0x0200 /* the buffer of this message is DMA safe */
30 /* makes only sense in kernelspace */
31 /* userspace buffers are copied anyway */
32 #define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */
33 #define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */
34 #define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */
35 #define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */
36 #define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_NOSTART */
37 #define I2C_M_STOP 0x8000 /* if I2C_FUNC_PROTOCOL_MANGLING */
38 unsigned short len; /* msg length */
39 unsigned char *buf; /* pointer to msg data */
40 } LzI2cMsg;
41
42 /**
43 * @brief Initializes an I2C device with a specified baud rate.
44 *
45 *
46 *
47 * @param id Indicates the I2C device ID.
48 * @param freq Indicates the scl frequency to set, unit is HZ.
49 * @return Returns {@link LZ_HARDWARE_SUCCESS} if the I2C device is initialized;
50 * returns {@link LZ_HARDWARE_FAILURE} otherwise. For details about other return values, see the chip description.
51 */
52 unsigned int LzI2cInit(unsigned int id, unsigned int freq);
53
54 /**
55 * @brief Deinitializes an I2C device.
56 *
57 * @param id Indicates the I2C device ID.
58 * @return Returns {@link LZ_HARDWARE_SUCCESS} if the I2C device is deinitialized;
59 * returns {@link LZ_HARDWARE_FAILURE} otherwise. For details about other return values, see the chip description.
60 */
61 unsigned int LzI2cDeinit(unsigned int id);
62
63 /**
64 * @brief Sets the scl frequency for an I2C device.
65 *
66 * @param id Indicates the I2C device ID.
67 * @param freq Indicates the scl frequency to set, unit is HZ.
68 * @return Returns {@link LZ_HARDWARE_SUCCESS} if the scl frequency is set;
69 * returns {@link LZ_HARDWARE_FAILURE} otherwise. For details about other return values, see the chip description.
70 */
71 unsigned int LzI2cSetFreq(unsigned int id, unsigned int freq);
72
73 /**
74 * @brief Transfer data from/to an I2C device based on flags.
75 *
76 * @param id Indicates the I2C device ID.
77 * @param msgs Indicates the point of i2c messages.
78 * @param num Indicates the number of message to transfer.
79 * @return Returns {@link LZ_HARDWARE_SUCCESS} if the data is written to the I2C device successfully;
80 * returns {@link LZ_HARDWARE_FAILURE} otherwise. For details about other return values, see the chip description.
81 */
82 unsigned int LzI2cTransfer(unsigned id, LzI2cMsg *msgs, unsigned int num);
83 /**
84 * @brief Write data to an I2C device.
85 *
86 * @param id Indicates the I2C device ID.
87 * @param slaveAddr Indicates the I2C slave device address.
88 * @param data Indicates the data to write.
89 * @param len Indicates the bytes of the data to write.
90 * @return Returns {@link LZ_HARDWARE_SUCCESS} if the data is written to the I2C device successfully;
91 * returns {@link LZ_HARDWARE_FAILURE} otherwise. For details about other return values, see the chip description.
92 */
LzI2cWrite(unsigned int id,unsigned short slaveAddr,const unsigned char * data,unsigned int len)93 static inline unsigned int LzI2cWrite(unsigned int id, unsigned short slaveAddr,
94 const unsigned char *data, unsigned int len)
95 {
96 LzI2cMsg msg;
97
98 msg.addr = slaveAddr;
99 msg.flags = 0;
100 msg.buf = (unsigned char *)data;
101 msg.len = len;
102
103 return LzI2cTransfer(id, &msg, 1);
104 }
105
106 /**
107 * @brief Read data from an I2C device.
108 *
109 * @param id Indicates the I2C device ID.
110 * @param slaveAddr Indicates the I2C slave device address.
111 * @param data Indicates the data buffer to read.
112 * @param len Indicates the bytes of the data to read.
113 * @return Returns {@link LZ_HARDWARE_SUCCESS} if the data is written to the I2C device successfully;
114 * returns {@link LZ_HARDWARE_FAILURE} otherwise. For details about other return values, see the chip description.
115 */
LzI2cRead(unsigned int id,unsigned short slaveAddr,unsigned char * data,unsigned int len)116 static inline unsigned int LzI2cRead(unsigned int id, unsigned short slaveAddr, unsigned char *data, unsigned int len)
117 {
118 LzI2cMsg msg;
119
120 msg.addr = slaveAddr;
121 msg.flags = I2C_M_RD;
122 msg.buf = data;
123 msg.len = len;
124
125 return LzI2cTransfer(id, &msg, 1);
126 }
127
128 /**
129 * @brief Write the data to the register address of an I2C device.
130 *
131 * @param id Indicates the I2C device ID.
132 * @param slaveAddr Indicates the I2C slave device address.
133 * @param regAddr Indicates the register address.
134 * @param regLen Indicates the bytes of register address.
135 * @param data Indicates the data buffer to write.
136 * @param len Indicates the bytes of the data to write.
137 * @return Returns {@link LZ_HARDWARE_SUCCESS} if the data is written to the I2C device successfully;
138 * returns {@link LZ_HARDWARE_FAILURE} otherwise. For details about other return values, see the chip description.
139 */
LzI2cWriteReg(unsigned int id,unsigned short slaveAddr,unsigned char * regAddr,unsigned int regLen,unsigned char * data,unsigned int len)140 static inline unsigned int LzI2cWriteReg(unsigned int id, unsigned short slaveAddr,
141 unsigned char *regAddr, unsigned int regLen,
142 unsigned char *data, unsigned int len)
143 {
144 unsigned int ret;
145 LzI2cMsg msg;
146 unsigned int count = regLen + len;
147
148 if (count == 0) {
149 return LZ_HARDWARE_FAILURE;
150 }
151
152 msg.addr = slaveAddr;
153 msg.flags = I2C_M_RD;
154 msg.buf = malloc(count);
155 if (msg.buf == NULL) {
156 return LZ_HARDWARE_FAILURE;
157 }
158 msg.len = count;
159
160 if (memcpy_s(msg.buf, count, regAddr, regLen) == NULL) {
161 return LZ_HARDWARE_FAILURE;
162 }
163 if (memcpy_s(msg.buf + regLen, len, data, len) == NULL) {
164 return LZ_HARDWARE_FAILURE;
165 }
166
167 ret = LzI2cTransfer(id, &msg, 1);
168 free(msg.buf);
169
170 return ret;
171 }
172
173 /**
174 * @brief Write register address and read the register value from an I2C device.
175 *
176 * @param id Indicates the I2C device ID.
177 * @param slaveAddr Indicates the I2C slave device address.
178 * @param regAddr Indicates the register address.
179 * @param regLen Indicates the bytes of register address.
180 * @param data Indicates the data buffer to read.
181 * @param len Indicates the bytes of the data to read.
182 * @return Returns {@link LZ_HARDWARE_SUCCESS} if the data is written to the I2C device successfully;
183 * returns {@link LZ_HARDWARE_FAILURE} otherwise. For details about other return values, see the chip description.
184 */
LzI2cReadReg(unsigned int id,unsigned short slaveAddr,unsigned char * regAddr,unsigned int regLen,unsigned char * data,unsigned int len)185 static inline unsigned int LzI2cReadReg(unsigned int id, unsigned short slaveAddr,
186 unsigned char *regAddr, unsigned int regLen,
187 unsigned char *data, unsigned int len)
188 {
189 #define I2C_MSGS_MAX 2 // LzI2cMsg数组个数
190 LzI2cMsg msgs[I2C_MSGS_MAX];
191
192 msgs[0].addr = slaveAddr;
193 msgs[0].flags = 0;
194 msgs[0].buf = regAddr;
195 msgs[0].len = regLen;
196
197 msgs[1].addr = slaveAddr;
198 msgs[1].flags = I2C_M_RD;
199 msgs[1].buf = data;
200 msgs[1].len = len;
201
202 return LzI2cTransfer(id, msgs, I2C_MSGS_MAX);
203 }
204
205 #endif