F´ Flight Software - C/C++ Documentation  devel
A framework for building embedded system applications to NASA flight quality standards.
LinuxI2cDriver.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title LinuxI2cDriverComponentImpl.cpp
3 // \author tcanham
4 // \brief cpp file for LinuxI2cDriver component implementation class
5 //
6 // \copyright
7 // Copyright 2009-2015, by the California Institute of Technology.
8 // ALL RIGHTS RESERVED. United States Government Sponsorship
9 // acknowledged.
10 //
11 // ======================================================================
12 
13 #include "Fw/Types/Assert.hpp"
14 #include <FpConfig.hpp>
16 #include <Fw/Logger/Logger.hpp>
17 
18 #include <unistd.h> // required for I2C device access
19 #include <fcntl.h> // required for I2C device configuration
20 #include <sys/ioctl.h> // required for I2C device usage
21 #include <linux/i2c.h> // required for struct / constant definitions
22 #include <linux/i2c-dev.h> // required for constant definitions
23 #include <cerrno>
24 
25 #define DEBUG_PRINT 0
26 
27 namespace Drv {
28 
29  // ----------------------------------------------------------------------
30  // Construction, initialization, and destruction
31  // ----------------------------------------------------------------------
32 
35  const char *const compName
36  ) : LinuxI2cDriverComponentBase(compName),
37  m_fd(-1)
38  {
39 
40  }
41 
44  {
45  if (-1 != this->m_fd) { // check if file is open
46  ::close(this->m_fd);
47  }
48  }
49 
50  bool LinuxI2cDriver::open(const char* device) {
51  FW_ASSERT(device);
52  this->m_fd = ::open(device, O_RDWR);
53  return (-1 != this->m_fd);
54  }
55 
56 
57  // ----------------------------------------------------------------------
58  // Handler implementations for user-defined typed input ports
59  // ----------------------------------------------------------------------
60 
61  // Note this port handler is guarded, so we can make the ioctl call
62 
63  Drv::I2cStatus LinuxI2cDriver ::
64  write_handler(
65  const NATIVE_INT_TYPE portNum,
66  U32 addr,
67  Fw::Buffer &serBuffer
68  )
69  {
70  // Make sure file has been opened
71  if (-1 == this->m_fd) {
73  }
74 
75 #if DEBUG_PRINT
76  Fw::Logger::log("I2c addr: 0x%02X\n",addr);
77  for (U32 byte = 0; byte < serBuffer.getSize(); byte++) {
78  Fw::Logger::log("0x%02X ",serBuffer.getData()[byte]);
79 
80  }
81  Fw::Logger::log("\n");
82 #endif
83  // select slave address
84  int stat = ioctl(this->m_fd, I2C_SLAVE, addr);
85  if (stat == -1) {
86 #if DEBUG_PRINT
87  Fw::Logger::log("Status: %d Errno: %d\n", stat, errno);
88 #endif
90  }
91  // make sure it isn't a null pointer
92  FW_ASSERT(serBuffer.getData());
93  // write data
94  stat = static_cast<int>(write(this->m_fd, serBuffer.getData(), serBuffer.getSize()));
95  if (stat == -1) {
96 #if DEBUG_PRINT
97  Fw::Logger::log("Status: %d Errno: %d\n", stat, errno);
98 #endif
100  }
101  return I2cStatus::I2C_OK;
102  }
103 
104  Drv::I2cStatus LinuxI2cDriver ::
105  read_handler(
106  const NATIVE_INT_TYPE portNum,
107  U32 addr,
108  Fw::Buffer &serBuffer
109  )
110  {
111  // Make sure file has been opened
112  if (-1 == this->m_fd) {
114  }
115 
116 #if DEBUG_PRINT
117  Fw::Logger::log("I2c addr: 0x%02X\n",addr);
118 #endif
119  // select slave address
120  int stat = ioctl(this->m_fd, I2C_SLAVE, addr);
121  if (stat == -1) {
122 #if DEBUG_PRINT
123  Fw::Logger::log("Status: %d Errno: %d\n", stat, errno);
124 #endif
126  }
127  // make sure it isn't a null pointer
128  FW_ASSERT(serBuffer.getData());
129  // read data
130  stat = static_cast<int>(read(this->m_fd, serBuffer.getData(), serBuffer.getSize()));
131  if (stat == -1) {
132 #if DEBUG_PRINT
133  Fw::Logger::log("Status: %d Errno: %d\n", stat, errno);
134 #endif
136  }
137 #if DEBUG_PRINT
138  for (U32 byte = 0; byte < serBuffer.getSize(); byte++) {
139  Fw::Logger::log("0x%02X ",serBuffer.getData()[byte]);
140 
141  }
142  Fw::Logger::log("\n");
143 #endif
144  return I2cStatus::I2C_OK;
145  }
146 
147  Drv::I2cStatus LinuxI2cDriver ::
148  writeRead_handler(
149  const NATIVE_INT_TYPE portNum,
150  U32 addr,
151  Fw::Buffer &writeBuffer,
152  Fw::Buffer &readBuffer
153  ){
154 
155  // Make sure file has been opened
156  if (-1 == this->m_fd) {
158  }
159  FW_ASSERT(-1 != this->m_fd);
160 
161  // make sure they are not null pointers
162  FW_ASSERT(writeBuffer.getData());
163  FW_ASSERT(readBuffer.getData());
164 
165  #if DEBUG_PRINT
166  Fw::Logger::log("I2c addr: 0x%02X\n",addr);
167  #endif
168 
169  struct i2c_msg rdwr_msgs[2];
170 
171  // Start address
172  rdwr_msgs[0].addr = static_cast<U16>(addr);
173  rdwr_msgs[0].flags = 0; // write
174  rdwr_msgs[0].len = static_cast<U16>(writeBuffer.getSize());
175  rdwr_msgs[0].buf = writeBuffer.getData();
176 
177  // Read buffer
178  rdwr_msgs[1].addr = static_cast<U16>(addr);
179  rdwr_msgs[1].flags = I2C_M_RD; // read
180  rdwr_msgs[1].len = static_cast<U16>(readBuffer.getSize());
181  rdwr_msgs[1].buf = readBuffer.getData();
182 
183  struct i2c_rdwr_ioctl_data rdwr_data;
184  rdwr_data.msgs = rdwr_msgs;
185  rdwr_data.nmsgs = 2;
186 
187  //Use ioctl to perform the combined write/read transaction
188  NATIVE_INT_TYPE stat = ioctl(this->m_fd, I2C_RDWR, &rdwr_data);
189 
190  if(stat == -1){
191  #if DEBUG_PRINT
192  Fw::Logger::log("Status: %d Errno: %d\n", stat, errno);
193  #endif
194  //Because we're using ioctl to perform the transaction we dont know exactly the type of error that occurred
196  }
197 
198 #if DEBUG_PRINT
199  Fw::Logger::log("Wrote:\n");
200  for (U32 byte = 0; byte < writeBuffer.getSize(); byte++) {
201  Fw::Logger::log("0x%02X ",writeBuffer.getData()[byte]);
202 
203  }
204  Fw::Logger::log("\n");
205  Fw::Logger::log("Read:\n");
206  for (U32 byte = 0; byte < readBuffer.getSize(); byte++) {
207  Fw::Logger::log("0x%02X ",readBuffer.getData()[byte]);
208 
209  }
210  Fw::Logger::log("\n");
211 #endif
212 
213  return I2cStatus::I2C_OK;
214  }
215 
216 } // end namespace Drv
#define FW_ASSERT(...)
Definition: Assert.hpp:14
PlatformIntType NATIVE_INT_TYPE
Definition: BasicTypes.h:55
C++-compatible configuration header for fprime configuration.
@ I2C_OPEN_ERR
I2C driver failed to open device.
@ I2C_OTHER_ERR
Other errors that don't fit.
@ I2C_WRITE_ERR
I2C write failed.
@ I2C_OK
Transaction okay.
@ I2C_ADDRESS_ERR
I2C address invalid.
@ I2C_READ_ERR
I2C read failed.
Auto-generated base for LinuxI2cDriver component.
LinuxI2cDriver(const char *const compName)
bool open(const char *device)
U8 * getData() const
Definition: Buffer.cpp:68
U32 getSize() const
Definition: Buffer.cpp:72
static void log(const char *format,...)
log a formated string with supplied arguments
Definition: Logger.cpp:21