Statistics
| Branch: | Revision:

ddr4s / fw / wiringPi / wiringPi / wiringPiI2C.c @ 32:cadb9025f1e0

History | View | Annotate | Download (6.25 KB)

1
/*
2
 * wiringPiI2C.c:
3
 *        Simplified I2C access routines
4
 *        Copyright (c) 2013 Gordon Henderson
5
 ***********************************************************************
6
 * This file is part of wiringPi:
7
 *        https://projects.drogon.net/raspberry-pi/wiringpi/
8
 *
9
 *    wiringPi is free software: you can redistribute it and/or modify
10
 *    it under the terms of the GNU Lesser General Public License as
11
 *    published by the Free Software Foundation, either version 3 of the
12
 *    License, or (at your option) any later version.
13
 *
14
 *    wiringPi is distributed in the hope that it will be useful,
15
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 *    GNU Lesser General Public License for more details.
18
 *
19
 *    You should have received a copy of the GNU Lesser General Public
20
 *    License along with wiringPi.
21
 *    If not, see <http://www.gnu.org/licenses/>.
22
 ***********************************************************************
23
 */
24

    
25
/*
26
 * Notes:
27
 *        The Linux I2C code is actually the same (almost) as the SMBus code.
28
 *        SMBus is System Management Bus - and in essentially I2C with some
29
 *        additional functionality added, and stricter controls on the electrical
30
 *        specifications, etc. however I2C does work well with it and the
31
 *        protocols work over both.
32
 *
33
 *        I'm directly including the SMBus functions here as some Linux distros
34
 *        lack the correct header files, and also some header files are GPLv2
35
 *        rather than the LGPL that wiringPi is released under - presumably because
36
 *        originally no-one expected I2C/SMBus to be used outside the kernel -
37
 *        however enter the Raspberry Pi with people now taking directly to I2C
38
 *        devices without going via the kernel...
39
 *
40
 *        This may ultimately reduce the flexibility of this code, but it won't be
41
 *        hard to maintain it and keep it current, should things change.
42
 *
43
 *        Information here gained from: kernel/Documentation/i2c/dev-interface
44
 *        as well as other online resources.
45
 *********************************************************************************
46
 */
47

    
48
#include <stdio.h>
49
#include <stdlib.h>
50
#include <stdint.h>
51
#include <errno.h>
52
#include <string.h>
53
#include <fcntl.h>
54
#include <sys/ioctl.h>
55
#include <asm/ioctl.h>
56

    
57
#include "wiringPi.h"
58
#include "wiringPiI2C.h"
59

    
60
// I2C definitions
61

    
62
#define I2C_SLAVE        0x0703
63
#define I2C_SMBUS        0x0720        /* SMBus-level access */
64

    
65
#define I2C_SMBUS_READ        1
66
#define I2C_SMBUS_WRITE        0
67

    
68
// SMBus transaction types
69

    
70
#define I2C_SMBUS_QUICK                    0
71
#define I2C_SMBUS_BYTE                    1
72
#define I2C_SMBUS_BYTE_DATA            2 
73
#define I2C_SMBUS_WORD_DATA            3
74
#define I2C_SMBUS_PROC_CALL            4
75
#define I2C_SMBUS_BLOCK_DATA            5
76
#define I2C_SMBUS_I2C_BLOCK_BROKEN  6
77
#define I2C_SMBUS_BLOCK_PROC_CALL   7                /* SMBus 2.0 */
78
#define I2C_SMBUS_I2C_BLOCK_DATA    8
79

    
80
// SMBus messages
81

    
82
#define I2C_SMBUS_BLOCK_MAX        32        /* As specified in SMBus standard */        
83
#define I2C_SMBUS_I2C_BLOCK_MAX        32        /* Not specified but we use same structure */
84

    
85
// Structures used in the ioctl() calls
86

    
87
union i2c_smbus_data
88
{
89
  uint8_t  byte ;
90
  uint16_t word ;
91
  uint8_t  block [I2C_SMBUS_BLOCK_MAX + 2] ;        // block [0] is used for length + one more for PEC
92
} ;
93

    
94
struct i2c_smbus_ioctl_data
95
{
96
  char read_write ;
97
  uint8_t command ;
98
  int size ;
99
  union i2c_smbus_data *data ;
100
} ;
101

    
102
static inline int i2c_smbus_access (int fd, char rw, uint8_t command, int size, union i2c_smbus_data *data)
103
{
104
  struct i2c_smbus_ioctl_data args ;
105

    
106
  args.read_write = rw ;
107
  args.command    = command ;
108
  args.size       = size ;
109
  args.data       = data ;
110
  return ioctl (fd, I2C_SMBUS, &args) ;
111
}
112

    
113

    
114
/*
115
 * wiringPiI2CRead:
116
 *        Simple device read
117
 *********************************************************************************
118
 */
119

    
120
int wiringPiI2CRead (int fd)
121
{
122
  union i2c_smbus_data data ;
123

    
124
  if (i2c_smbus_access (fd, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &data))
125
    return -1 ;
126
  else
127
    return data.byte & 0xFF ;
128
}
129

    
130

    
131
/*
132
 * wiringPiI2CReadReg8: wiringPiI2CReadReg16:
133
 *        Read an 8 or 16-bit value from a regsiter on the device
134
 *********************************************************************************
135
 */
136

    
137
int wiringPiI2CReadReg8 (int fd, int reg)
138
{
139
  union i2c_smbus_data data;
140

    
141
  if (i2c_smbus_access (fd, I2C_SMBUS_READ, reg, I2C_SMBUS_BYTE_DATA, &data))
142
    return -1 ;
143
  else
144
    return data.byte & 0xFF ;
145
}
146

    
147
int wiringPiI2CReadReg16 (int fd, int reg)
148
{
149
  union i2c_smbus_data data;
150

    
151
  if (i2c_smbus_access (fd, I2C_SMBUS_READ, reg, I2C_SMBUS_WORD_DATA, &data))
152
    return -1 ;
153
  else
154
    return data.word & 0xFFFF ;
155
}
156

    
157

    
158
/*
159
 * wiringPiI2CWrite:
160
 *        Simple device write
161
 *********************************************************************************
162
 */
163

    
164
int wiringPiI2CWrite (int fd, int data)
165
{
166
  return i2c_smbus_access (fd, I2C_SMBUS_WRITE, data, I2C_SMBUS_BYTE, NULL) ;
167
}
168

    
169

    
170
/*
171
 * wiringPiI2CWriteReg8: wiringPiI2CWriteReg16:
172
 *        Write an 8 or 16-bit value to the given register
173
 *********************************************************************************
174
 */
175

    
176
int wiringPiI2CWriteReg8 (int fd, int reg, int value)
177
{
178
  union i2c_smbus_data data ;
179

    
180
  data.byte = value ;
181
  return i2c_smbus_access (fd, I2C_SMBUS_WRITE, reg, I2C_SMBUS_BYTE_DATA, &data) ;
182
}
183

    
184
int wiringPiI2CWriteReg16 (int fd, int reg, int value)
185
{
186
  union i2c_smbus_data data ;
187

    
188
  data.word = value ;
189
  return i2c_smbus_access (fd, I2C_SMBUS_WRITE, reg, I2C_SMBUS_WORD_DATA, &data) ;
190
}
191

    
192

    
193
/*
194
 * wiringPiI2CSetupInterface:
195
 *        Undocumented access to set the interface explicitly - might be used
196
 *        for the Pi's 2nd I2C interface...
197
 *********************************************************************************
198
 */
199

    
200
int wiringPiI2CSetupInterface (const char *device, int devId)
201
{
202
  int fd ;
203

    
204
  if ((fd = open (device, O_RDWR)) < 0)
205
    return wiringPiFailure (WPI_ALMOST, "Unable to open I2C device: %s\n", strerror (errno)) ;
206

    
207
  if (ioctl (fd, I2C_SLAVE, devId) < 0)
208
    return wiringPiFailure (WPI_ALMOST, "Unable to select I2C device: %s\n", strerror (errno)) ;
209

    
210
  return fd ;
211
}
212

    
213

    
214
/*
215
 * wiringPiI2CSetup:
216
 *        Open the I2C device, and regsiter the target device
217
 *********************************************************************************
218
 */
219

    
220
int wiringPiI2CSetup (const int devId)
221
{
222
  int rev ;
223
  const char *device ;
224

    
225
  rev = piGpioLayout () ;
226

    
227
  if (rev == 1)
228
    device = "/dev/i2c-0" ;
229
  else
230
    device = "/dev/i2c-1" ;
231

    
232
  return wiringPiI2CSetupInterface (device, devId) ;
233
}