GCC Code Coverage Report


Directory: ./
File: oled/I2C.c
Date: 2026-10-29 08:11:58
Exec Total Coverage
Lines: 28 76 36.8%
Functions: 6 11 54.5%
Branches: 8 38 21.1%

Line Branch Exec Source
1 /*
2 * MIT License
3
4 Copyright (c) 2017 DeeplyEmbedded
5
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in all
14 copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 SOFTWARE.
23
24 * I2C.c
25 *
26 * Created on : September 19, 2017
27 * Author : Vinay Divakar
28 * Description : This is an I2C Library for the BeagleBone that consists of the API's to support the standard
29 * I2C operations.
30 * Website : www.deeplyembedded.org
31 */
32
33 /*Libs Includes*/
34 #include <linux/i2c-dev.h>
35 #include <linux/i2c.h>
36 #include <sys/ioctl.h>
37 #include <fcntl.h>
38 #include <stdio.h>
39 #include <unistd.h>
40
41 /* Header Files */
42 #include "I2C.h"
43
44 /* Exposed objects for i2c-x */
45 I2C_DeviceT I2C_DEV_2;
46
47 /****************************************************************
48 * Function Name : Open_device
49 * Description : Opens the I2C device to use
50 * Returns : 0 on success, -1 on failure
51 * Params @i2c_dev_path: Path to the I2C device
52 * @fd: Variable to store the file handler
53 ****************************************************************/
54 12 int Open_device(const char* i2c_dev_path, int* fd) {
55
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if ((*fd = open(i2c_dev_path, O_RDWR)) < 0)
56 ✗ return -1;
57 else
58 12 return 0;
59 }
60
61 /****************************************************************
62 * Function Name : Close_device
63 * Description : Closes the I2C device in use
64 * Returns : 0 on success, -1 on failure
65 * Params : @fd: file descriptor
66 ****************************************************************/
67 ✗ int Close_device(int fd) {
68 ✗ if (close(fd) == -1)
69 ✗ return -1;
70 else
71 ✗ return 0;
72 }
73
74 /****************************************************************
75 * Function Name : Set_slave_addr
76 * Description : Connect to the Slave device
77 * Returns : 0 on success, -1 on failure
78 * Params @fd: File descriptor
79 * @slave_addr: Address of the slave device to
80 * talk to.
81 ****************************************************************/
82 12 int Set_slave_addr(int fd, unsigned char slave_addr) {
83
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (ioctl(fd, I2C_SLAVE, slave_addr) < 0)
84 ✗ return -1;
85 else
86 12 return 0;
87 }
88
89 /****************************************************************
90 * Function Name : i2c_write
91 * Description : Write a byte on SDA
92 * Returns : No. of bytes written on success, -1 on failure
93 * Params @fd: File descriptor
94 * @data: data to write on SDA
95 ****************************************************************/
96 ✗ int i2c_write(int fd, unsigned char data) {
97 ✗ int ret = 0;
98 ✗ ret = write(fd, &data, I2C_ONE_BYTE);
99 ✗ if ((ret == -1) || (ret != 1))
100 ✗ return -1;
101 else
102 ✗ return (ret);
103 }
104
105 /****************************************************************
106 * Function Name : i2c_read
107 * Description : Read a byte on SDA
108 * Returns : No. of bytes read on success, -1 on failure
109 * Params @fd: File descriptor
110 * @read_data: Points to the variable that stores
111 * the read data byte
112 ****************************************************************/
113 ✗ int i2c_read(int fd, unsigned char* read_data) {
114 ✗ int ret = 0;
115 ✗ ret = read(fd, &read_data, I2C_ONE_BYTE);
116 ✗ if (ret == -1)
117 ✗ perror("I2C: Failed to read |");
118 ✗ if (ret == 0)
119 ✗ perror("I2C: End of FILE |");
120 ✗ return (ret);
121 }
122
123 /****************************************************************
124 * Function Name : i2c_read_register
125 * Description : Read a single register of the slave device
126 * Returns : No. of bytes read on success, -1 on failure
127 * Params @fd: File descriptor
128 * @read_addr: Register address to be read
129 * @read_data: Points to the variable that stores
130 * the read data byte
131 ****************************************************************/
132 ✗ int i2c_read_register(int fd, unsigned char read_addr, unsigned char* read_data) {
133 ✗ int ret = 0;
134 ✗ if (i2c_write(fd, read_addr) == -1) {
135 ✗ perror("I2C: Failed to write |");
136 ✗ return -1;
137 }
138 ✗ ret = read(fd, &read_data, I2C_ONE_BYTE);
139 ✗ if (ret == -1)
140 ✗ perror("I2C: Failed to read |");
141 ✗ if (ret == 0)
142 ✗ perror("I2C: End of FILE |");
143 ✗ return (ret);
144 }
145
146 /****************************************************************
147 * Function Name : i2c_read_registers
148 * Description : Read a multiple registers on the slave device
149 * from starting address
150 * Returns : No. of bytes read on success, -1 on failure
151 * Params @fd: File descriptor
152 * @num: Number of registers/bytes to read from.
153 * @starting_addr: Starting address to read from
154 * @buff_Ptr: Buffer to store the read bytes
155 ****************************************************************/
156 ✗ int i2c_read_registers(int fd, int num, unsigned char starting_addr,
157 unsigned char* buff_Ptr) {
158 ✗ int ret = 0;
159 ✗ if (i2c_write(fd, starting_addr) == -1) {
160 ✗ perror("I2C: Failed to write |");
161 ✗ return -1;
162 }
163 ✗ ret = read(fd, buff_Ptr, num);
164 ✗ if (ret == -1)
165 ✗ perror("I2C: Failed to read |");
166 ✗ if (ret == 0)
167 ✗ perror("I2C: End of FILE |");
168 ✗ return (ret);
169 }
170
171 /****************************************************************
172 * Function Name : i2c_multiple_writes
173 * Description : Write multiple bytes on SDA
174 * Returns : No. of bytes written on success, -1 on failure
175 * Params @fd: file descriptor
176 * @num: No. of bytes to write
177 * @Ptr_buff: Pointer to the buffer containing the
178 * bytes to be written on the SDA
179 ****************************************************************/
180 664 int i2c_multiple_writes(int fd, int num, unsigned char* Ptr_buff) {
181 664 int ret = 0;
182 664 ret = write(fd, Ptr_buff, num);
183
2/4
✓ Branch 0 taken 664 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 664 times.
664 if ((ret == -1) || (ret != num))
184 ✗ return -1;
185 else
186 664 return (ret);
187 }
188
189 /****************************************************************
190 * Function Name : i2c_write_register
191 * Description : Write a control byte or byte to a register
192 * Returns : No. of bytes written on success, -1 on failure
193 * Params @fd: file descriptor
194 * @reg_addr_or_cntrl: Control byte or Register
195 * address to be written
196 * @val: Command or value to be written in the
197 * addressed register
198 ****************************************************************/
199 810 int i2c_write_register(int fd, unsigned char reg_addr_or_cntrl, unsigned char val) {
200 unsigned char buff[2];
201 810 int ret = 0;
202 810 buff[0] = reg_addr_or_cntrl;
203 810 buff[1] = val;
204 810 ret = write(fd, buff, I2C_TWO_BYTES);
205
2/4
✓ Branch 0 taken 810 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 810 times.
810 if ((ret == -1) || (ret != I2C_TWO_BYTES))
206 ✗ return -1;
207 else
208 810 return (ret);
209 }
210
211 /****************************************************************
212 * Function Name : config_i2c_struct
213 * Description : Initialize the I2C device structure
214 * Returns : NONE
215 * Params @i2c_dev_path: Device path
216 * @slave_addr: Slave device address
217 * @i2c_dev: Pointer to the device structure
218 ****************************************************************/
219 12 void config_i2c_struct(const char* i2c_dev_path, unsigned char slave_addr, I2C_DevicePtr i2c_dev) {
220 12 i2c_dev->i2c_dev_path = i2c_dev_path;
221 12 i2c_dev->fd_i2c = 0;
222 12 i2c_dev->i2c_slave_addr = slave_addr;
223 12 }
224
225 /****************************************************************
226 * Function Name : init_i2c_dev1
227 * Description : Connect the i2c-2 bus to the slave device
228 * Returns : 0 on success, -1 on failure
229 * Params @slave_addr: Slave device address
230 ****************************************************************/
231 12 int init_i2c_dev2(const char* i2cPath, unsigned char slave_address) {
232 12 config_i2c_struct(i2cPath, slave_address, &I2C_DEV_2);
233
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (Open_device(I2C_DEV_2.i2c_dev_path, &I2C_DEV_2.fd_i2c) == -1) {
234 ✗ perror("I2C: Failed to open device |");
235 ✗ return -1;
236 }
237
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (Set_slave_addr(I2C_DEV_2.fd_i2c, I2C_DEV_2.i2c_slave_addr) == -1) {
238 ✗ perror("I2C: Failed to connect to slave device |");
239 ✗ return -1;
240 }
241
242 12 return 0;
243 }
244