i2c  1.4.2
RoadNarrows Robotics I2C Package
smbus.c
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: I2C
4 //
5 // Library: libi2c API
6 //
7 // File: smbus.c
8 //
9 /*! \file
10  *
11  * $LastChangedDate: 2009-09-09 09:44:12 -0600 (Wed, 09 Sep 2009) $
12  * $Rev: 130 $
13  *
14  * \brief System Management Bus (SMBus) over I<sup>2</sup>C communication
15  * interface.
16  *
17  * \author Robin Knight (robin.knight@roadnarrows.com)
18  *
19  * \copyright
20  * \h_copy 2009-2017. RoadNarrows LLC.\n
21  * http://www.roadnarrows.com\n
22  * All Rights Reserved
23  *
24  * <hr>
25  * \par Original Source and Copyright:
26  * See i2c-dev.h.
27  *
28  * <hr>
29  */
30 // Permission is hereby granted, without written agreement and without
31 // license or royalty fees, to use, copy, modify, and distribute this
32 // software and its documentation for any purpose, provided that
33 // (1) The above copyright notice and the following two paragraphs
34 // appear in all copies of the source code and (2) redistributions
35 // including binaries reproduces these notices in the supporting
36 // documentation. Substantial modifications to this software may be
37 // copyrighted by their authors and need not follow the licensing terms
38 // described here, provided that the new terms are clearly indicated in
39 // all files where they apply.
40 //
41 // IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY MEMBERS/EMPLOYEES
42 // OF ROADNARROW LLC OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY
43 // PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
44 // DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
45 // EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF
46 // THE POSSIBILITY OF SUCH DAMAGE.
47 //
48 // THE AUTHOR AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
49 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
50 // FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
51 // "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
52 // PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
53 //
54 ////////////////////////////////////////////////////////////////////////////////
55 
56 #include <stdlib.h>
57 #include <unistd.h>
58 #include <fcntl.h>
59 #include <sys/types.h>
60 #include <sys/errno.h>
61 #include <sys/ioctl.h>
62 
63 #include "rnr/rnrconfig.h"
64 #include "rnr/i2c-dev.h"
65 #include "rnr/smbus.h"
66 
67 
68 /*!
69  * \brief Execute an SMBus IOCTL.
70  *
71  * \param fd File descriptor to opened SMBus device.
72  * \param read_write Operation access type.
73  * \param command Operation command or immediate data.
74  * \param size Data size.
75  * \param [in,out] data Read/write/control data
76  *
77  * \return
78  * Returns \h_ge 0 on success.
79  * Else errno is set appropriately and -1 is returned.
80  */
81 int i2c_smbus_access(int fd, byte_t read_write, byte_t command,
82  int size, i2c_smbus_data_t *data)
83 {
85 
86  args.read_write = read_write;
87  args.command = command;
88  args.size = size;
89  args.data = data;
90 
91  return ioctl(fd, I2C_SMBUS, &args);
92 }
93 
94 /*!
95  * \brief Write a quick value to the SMBus.
96  *
97  * \param fd File descriptor to opened SMBus device.
98  * \param value Value to write
99  *
100  * \return
101  * Returns \h_ge 0 on success.
102  * Else errno is set appropriately and -1 is returned.
103  */
104 int i2c_smbus_write_quick(int fd, byte_t value)
105 {
106  return i2c_smbus_access(fd, value, I2C_NOCMD, I2C_SMBUS_QUICK, NULL);
107 }
108 
109 /*!
110  * \brief Read an immediate byte from the SMBus.
111  *
112  * \param fd File descriptor to opened SMBus device.
113  *
114  * \return
115  * Returns read byte on on success.
116  * Else errno is set appropriately and -1 is returned.
117  */
119 {
120  i2c_smbus_data_t data;
121  int rc;
122 
124 
125  return rc>=0? 0x0FF & data.byte: -1;
126 }
127 
128 /*!
129  * \brief Write an immediate byte to the SMBus.
130  *
131  * \param fd File descriptor to opened SMBus device.
132  * \param value Byte value to write.
133  *
134  * \return
135  * Returns \h_ge 0 on success.
136  * Else errno is set appropriately and -1 is returned.
137  */
138 int i2c_smbus_write_byte(int fd, byte_t value)
139 {
140  return i2c_smbus_access(fd, I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL);
141 }
142 
143 /*!
144  * \brief Read a data byte from the SMBus.
145  *
146  * \param fd File descriptor to opened SMBus device.
147  * \param command Command to SMBus device.
148  *
149  * \return
150  * Returns read byte on on success.
151  * Else errno is set appropriately and -1 is returned.
152  */
153 int i2c_smbus_read_byte_data(int fd, byte_t command)
154 {
155  i2c_smbus_data_t data;
156  int rc;
157 
159  &data);
160 
161  return rc>=0? 0x0FF & data.byte: -1;
162 }
163 
164 /*!
165  * \brief Write a data byte to the SMBus.
166  *
167  * \param fd File descriptor to opened SMBus device.
168  * \param command Command to SMBus device.
169  * \param value Byte value to write.
170  *
171  * \return
172  * Returns \h_ge 0 on success.
173  * Else errno is set appropriately and -1 is returned.
174  */
175 int i2c_smbus_write_byte_data(int fd, byte_t command, byte_t value)
176 {
177  i2c_smbus_data_t data;
178 
179  data.byte = value;
180 
181  return i2c_smbus_access(fd, I2C_SMBUS_WRITE, command,
182  I2C_SMBUS_BYTE_DATA, &data);
183 }
184 
185 /*!
186  * \brief Read a data 2-byte word from the SMBus.
187  *
188  * \param fd File descriptor to opened SMBus device.
189  * \param command Command to SMBus device.
190  *
191  * \return
192  * Returns read 2-byte word on on success.
193  * Else errno is set appropriately and -1 is returned.
194  */
195 int i2c_smbus_read_word_data(int fd, byte_t command)
196 {
197  i2c_smbus_data_t data;
198  int rc;
199 
201  &data);
202 
203  return rc>=0? 0x0FFFF & data.word: -1;
204 }
205 
206 /*!
207  * \brief Write a data 2-byte word to the SMBus.
208  *
209  * \param fd File descriptor to opened SMBus device.
210  * \param command Command to SMBus device.
211  * \param value Word value to write.
212  *
213  * \return
214  * Returns \h_ge 0 on success.
215  * Else errno is set appropriately and -1 is returned.
216  */
217 int i2c_smbus_write_word_data(int fd, byte_t command, ushort_t value)
218 {
219  i2c_smbus_data_t data;
220 
221  data.word = value;
222 
223  return i2c_smbus_access(fd, I2C_SMBUS_WRITE, command,
224  I2C_SMBUS_WORD_DATA, &data);
225 }
226 
227 /*!
228  * \brief Issue a 2-byte word process call (write/read) to the SMBus.
229  *
230  * \param fd File descriptor to opened SMBus device.
231  * \param command Command to SMBus device.
232  * \param value Word value to write.
233  *
234  * \return
235  * Returns read 2-byte word on on success.
236  * Else errno is set appropriately and -1 is returned.
237  */
238 int i2c_smbus_process_call(int fd, byte_t command, ushort_t value)
239 {
240  i2c_smbus_data_t data;
241  int rc;
242 
243  data.word = value;
244 
246  &data);
247 
248  return rc>=0? 0x0FFFF & data.word: -1;
249 }
250 
251 
252 /*!
253  * \brief Read a block of data from the SMBus.
254  *
255  * \param fd File descriptor to opened SMBus device.
256  * \param command Command to SMBus device.
257  * \param [out] values Buffer to hold the block of read byte values.\n
258  * Must be large enough to receive the data.
259  *
260  * \return
261  * On success, returns \h_ge 0 the number of bytes read, excluding any header
262  * fields. Else errno is set appropriately and -1 is returned.
263  */
264 int i2c_smbus_read_block_data(int fd, byte_t command, byte_t *values)
265 {
266  i2c_smbus_data_t data;
267  int i;
268  int rc;
269 
271  &data);
272 
273  if( rc >= 0 )
274  {
275  for(i=1; i<=data.block[0]; ++i)
276  {
277  values[i-1] = data.block[i];
278  }
279  rc = data.block[0];
280  }
281 
282  return rc;
283 }
284 
285 /*!
286  * \brief Write a data block to the SMBus.
287  *
288  * \param fd File descriptor to opened SMBus device.
289  * \param command Command to SMBus device.
290  * \param length Length of buffer (bytes) to write.
291  * \param [in] values Buffer of data to write.
292  *
293  * \return
294  * Returns \h_ge 0 on success.
295  * Else errno is set appropriately and -1 is returned.
296  */
297 int i2c_smbus_write_block_data(int fd, byte_t command, byte_t length,
298  const byte_t *values)
299 {
300  i2c_smbus_data_t data;
301  int i;
302 
303  if( length > I2C_SMBUS_BLOCK_MAX )
304  {
305  length = I2C_SMBUS_BLOCK_MAX;
306  }
307 
308  for(i=1; i<=length; i++)
309  {
310  data.block[i] = values[i-1];
311  }
312  data.block[0] = length;
313 
314  return i2c_smbus_access(fd, I2C_SMBUS_WRITE, command,
315  I2C_SMBUS_BLOCK_DATA, &data);
316 }
317 
318 /*!
319  * \brief Read a block of data from the SMBus via low-level I<sup>2</sup>C.
320  *
321  * \param fd File descriptor to opened SMBus device.
322  * \param command Command to SMBus device.
323  * \param [out] values Buffer to hold the block of read byte values.\n
324  * Must be large enough to receive the data.
325  *
326  * \return
327  * On success, returns \h_ge 0 the number of bytes read, excluding any header
328  * fields. Else errno is set appropriately and -1 is returned.
329  */
330 int i2c_smbus_read_i2c_block_data(int fd, byte_t command, byte_t *values)
331 {
332  i2c_smbus_data_t data;
333  int i;
334  int rc;
335 
337  &data);
338  if( rc >= 0 )
339  {
340  for(i=1; i<=data.block[0]; i++)
341  {
342  values[i-1] = data.block[i];
343  }
344  rc = data.block[0];
345  }
346  return rc;
347 }
348 
349 /*!
350  * \brief Write a block of data to the SMBus via low-level I<sup>2</sup>C.
351  *
352  * \param fd File descriptor to opened SMBus device.
353  * \param command Command to SMBus device.
354  * \param length Length of buffer (bytes) to write.
355  * \param [in] values Buffer of data to write.
356  *
357  * \return
358  * Returns \h_ge 0 on success.
359  * Else errno is set appropriately and -1 is returned.
360  */
361 int i2c_smbus_write_i2c_block_data(int fd, byte_t command, byte_t length,
362  const byte_t *values)
363 {
364  i2c_smbus_data_t data;
365  int i;
366 
367  if( length > I2C_SMBUS_I2C_BLOCK_MAX )
368  {
369  length = I2C_SMBUS_I2C_BLOCK_MAX;
370  }
371 
372  for(i=1; i<=length; i++)
373  {
374  data.block[i] = values[i-1];
375  }
376  data.block[0] = length;
377 
378  return i2c_smbus_access(fd, I2C_SMBUS_WRITE, command,
379  I2C_SMBUS_I2C_BLOCK_DATA, &data);
380 }
381 
382 /*!
383  * \brief Issue a block process call (write/read) to the SMBus.
384  *
385  * \param fd File descriptor to opened SMBus device.
386  * \param command Command to SMBus device.
387  * \param length Length of buffer (bytes) to write.
388  * \param [in,out] values Buffer of data to write and to hold the block of
389  * read byte values.\n
390  * Must be large enough to receive the data.
391  *
392  * \return
393  * On success, returns \h_ge 0 the number of bytes read, excluding any header
394  * fields. Else errno is set appropriately and -1 is returned.
395  */
396 int i2c_smbus_block_process_call(int fd, byte_t command, byte_t length,
397  byte_t *values)
398 {
399  i2c_smbus_data_t data;
400  int i;
401  int rc;
402 
403  if( length > I2C_SMBUS_BLOCK_MAX )
404  {
405  length = I2C_SMBUS_BLOCK_MAX;
406  }
407 
408  for(i=1; i<=length; i++)
409  {
410  data.block[i] = values[i-1];
411  }
412  data.block[0] = length;
413 
415  &data);
416 
417  if( rc >= 0 )
418  {
419  for(i=1; i<=data.block[0]; i++)
420  {
421  values[i-1] = data.block[i];
422  }
423  rc = data.block[0];
424  }
425 
426  return rc;
427 }
byte_t block[32+2]
block[0] is used for length and one more for PEC
Definition: i2c-dev.h:188
#define I2C_NOCMD
no command
Definition: i2c-dev.h:220
byte_t byte
data byte
Definition: i2c-dev.h:186
int i2c_smbus_access(int fd, byte_t read_write, byte_t command, int size, i2c_smbus_data_t *data)
Execute an SMBus IOCTL.
Definition: smbus.c:81
#define I2C_SMBUS_READ
read
Definition: i2c-dev.h:195
int i2c_smbus_process_call(int fd, byte_t command, ushort_t value)
Issue a 2-byte word process call (write/read) to the SMBus.
Definition: smbus.c:238
#define I2C_SMBUS_WORD_DATA
data word r/w operation
Definition: i2c-dev.h:206
#define I2C_SMBUS_I2C_BLOCK_DATA
i2c format block r/w/ operation
Definition: i2c-dev.h:209
int i2c_smbus_read_byte(int fd)
Read an immediate byte from the SMBus.
Definition: smbus.c:118
#define I2C_SMBUS_I2C_BLOCK_MAX
Not specified - use same structure.
Definition: i2c-dev.h:179
int i2c_smbus_write_i2c_block_data(int fd, byte_t command, byte_t length, const byte_t *values)
Write a block of data to the SMBus via low-level I2C.
Definition: smbus.c:361
int i2c_smbus_write_quick(int fd, byte_t value)
Write a quick value to the SMBus.
Definition: smbus.c:104
#define I2C_SMBUS_BLOCK_DATA
data block r/w operation
Definition: i2c-dev.h:208
#define I2C_SMBUS_BYTE_DATA
data byte r/w operation
Definition: i2c-dev.h:205
ushort_t word
data short word
Definition: i2c-dev.h:187
#define I2C_SMBUS_PROC_CALL
issue word process call
Definition: i2c-dev.h:207
I2C SMBus Data Stucture.
Definition: i2c-dev.h:184
int i2c_smbus_read_word_data(int fd, byte_t command)
Read a data 2-byte word from the SMBus.
Definition: smbus.c:195
I2C SMBus IOCTL Call Structure.
Definition: i2c-dev.h:239
#define I2C_SMBUS_BLOCK_MAX
As specified in SMBus standard.
Definition: i2c-dev.h:178
I2C character device interface.
#define I2C_SMBUS_BLOCK_PROC_CALL
SMBus 2.0: issue block process call.
Definition: i2c-dev.h:210
int i2c_smbus_read_block_data(int fd, byte_t command, byte_t *values)
Read a block of data from the SMBus.
Definition: smbus.c:264
#define I2C_SMBUS
SMBus-level access.
Definition: i2c-dev.h:231
int i2c_smbus_write_byte_data(int fd, byte_t command, byte_t value)
Write a data byte to the SMBus.
Definition: smbus.c:175
int i2c_smbus_read_i2c_block_data(int fd, byte_t command, byte_t *values)
Read a block of data from the SMBus via low-level I2C.
Definition: smbus.c:330
int i2c_smbus_block_process_call(int fd, byte_t command, byte_t length, byte_t *values)
Issue a block process call (write/read) to the SMBus.
Definition: smbus.c:396
byte_t read_write
operation direction
Definition: i2c-dev.h:241
i2c_smbus_data_t * data
data
Definition: i2c-dev.h:244
#define I2C_SMBUS_BYTE
immediate r/w byte operation
Definition: i2c-dev.h:204
int i2c_smbus_write_block_data(int fd, byte_t command, byte_t length, const byte_t *values)
Write a data block to the SMBus.
Definition: smbus.c:297
#define I2C_SMBUS_WRITE
write
Definition: i2c-dev.h:196
#define I2C_SMBUS_QUICK
quick SMBus ioctl operation
Definition: i2c-dev.h:203
int i2c_smbus_write_byte(int fd, byte_t value)
Write an immediate byte to the SMBus.
Definition: smbus.c:138
System Management Bus (SMBus) over I2C communication interface declarations.
byte_t command
ioctl command
Definition: i2c-dev.h:242
int i2c_smbus_read_byte_data(int fd, byte_t command)
Read a data byte from the SMBus.
Definition: smbus.c:153
int i2c_smbus_write_word_data(int fd, byte_t command, ushort_t value)
Write a data 2-byte word to the SMBus.
Definition: smbus.c:217