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 
43  init(
44  const NATIVE_INT_TYPE instance
45  )
46  {
48  }
49 
52  {
53  if (-1 != this->m_fd) { // check if file is open
54  ::close(this->m_fd);
55  }
56  }
57 
58  bool LinuxI2cDriver::open(const char* device) {
59  FW_ASSERT(device);
60  this->m_fd = ::open(device, O_RDWR);
61  return (-1 != this->m_fd);
62  }
63 
64 
65  // ----------------------------------------------------------------------
66  // Handler implementations for user-defined typed input ports
67  // ----------------------------------------------------------------------
68 
69  // Note this port handler is guarded, so we can make the ioctl call
70 
71  Drv::I2cStatus LinuxI2cDriver ::
72  write_handler(
73  const NATIVE_INT_TYPE portNum,
74  U32 addr,
75  Fw::Buffer &serBuffer
76  )
77  {
78  // Make sure file has been opened
79  if (-1 == this->m_fd) {
81  }
82 
83 #if DEBUG_PRINT
84  Fw::Logger::logMsg("I2c addr: 0x%02X\n",addr);
85  for (U32 byte = 0; byte < serBuffer.getSize(); byte++) {
86  Fw::Logger::logMsg("0x%02X ",serBuffer.getData()[byte]);
87 
88  }
89  Fw::Logger::logMsg("\n");
90 #endif
91  // select slave address
92  int stat = ioctl(this->m_fd, I2C_SLAVE, addr);
93  if (stat == -1) {
94 #if DEBUG_PRINT
95  Fw::Logger::logMsg("Status: %d Errno: %d\n", stat, errno);
96 #endif
98  }
99  // make sure it isn't a null pointer
100  FW_ASSERT(serBuffer.getData());
101  // write data
102  stat = static_cast<int>(write(this->m_fd, serBuffer.getData(), serBuffer.getSize()));
103  if (stat == -1) {
104 #if DEBUG_PRINT
105  Fw::Logger::logMsg("Status: %d Errno: %d\n", stat, errno);
106 #endif
108  }
109  return I2cStatus::I2C_OK;
110  }
111 
112  Drv::I2cStatus LinuxI2cDriver ::
113  read_handler(
114  const NATIVE_INT_TYPE portNum,
115  U32 addr,
116  Fw::Buffer &serBuffer
117  )
118  {
119  // Make sure file has been opened
120  if (-1 == this->m_fd) {
122  }
123 
124 #if DEBUG_PRINT
125  Fw::Logger::logMsg("I2c addr: 0x%02X\n",addr);
126 #endif
127  // select slave address
128  int stat = ioctl(this->m_fd, I2C_SLAVE, addr);
129  if (stat == -1) {
130 #if DEBUG_PRINT
131  Fw::Logger::logMsg("Status: %d Errno: %d\n", stat, errno);
132 #endif
134  }
135  // make sure it isn't a null pointer
136  FW_ASSERT(serBuffer.getData());
137  // read data
138  stat = static_cast<int>(read(this->m_fd, serBuffer.getData(), serBuffer.getSize()));
139  if (stat == -1) {
140 #if DEBUG_PRINT
141  Fw::Logger::logMsg("Status: %d Errno: %d\n", stat, errno);
142 #endif
144  }
145 #if DEBUG_PRINT
146  for (U32 byte = 0; byte < serBuffer.getSize(); byte++) {
147  Fw::Logger::logMsg("0x%02X ",serBuffer.getData()[byte]);
148 
149  }
150  Fw::Logger::logMsg("\n");
151 #endif
152  return I2cStatus::I2C_OK;
153  }
154 
155  Drv::I2cStatus LinuxI2cDriver ::
156  writeRead_handler(
157  const NATIVE_INT_TYPE portNum,
158  U32 addr,
159  Fw::Buffer &writeBuffer,
160  Fw::Buffer &readBuffer
161  ){
162 
163  // Make sure file has been opened
164  if (-1 == this->m_fd) {
166  }
167  FW_ASSERT(-1 != this->m_fd);
168 
169  // make sure they are not null pointers
170  FW_ASSERT(writeBuffer.getData());
171  FW_ASSERT(readBuffer.getData());
172 
173  #if DEBUG_PRINT
174  Fw::Logger::logMsg("I2c addr: 0x%02X\n",addr);
175  #endif
176 
177  struct i2c_msg rdwr_msgs[2];
178 
179  // Start address
180  rdwr_msgs[0].addr = static_cast<U16>(addr);
181  rdwr_msgs[0].flags = 0; // write
182  rdwr_msgs[0].len = static_cast<U16>(writeBuffer.getSize());
183  rdwr_msgs[0].buf = writeBuffer.getData();
184 
185  // Read buffer
186  rdwr_msgs[1].addr = static_cast<U16>(addr);
187  rdwr_msgs[1].flags = I2C_M_RD; // read
188  rdwr_msgs[1].len = static_cast<U16>(readBuffer.getSize());
189  rdwr_msgs[1].buf = readBuffer.getData();
190 
191  struct i2c_rdwr_ioctl_data rdwr_data;
192  rdwr_data.msgs = rdwr_msgs;
193  rdwr_data.nmsgs = 2;
194 
195  //Use ioctl to perform the combined write/read transaction
196  NATIVE_INT_TYPE stat = ioctl(this->m_fd, I2C_RDWR, &rdwr_data);
197 
198  if(stat == -1){
199  #if DEBUG_PRINT
200  Fw::Logger::logMsg("Status: %d Errno: %d\n", stat, errno);
201  #endif
202  //Because we're using ioctl to perform the transaction we dont know exactly the type of error that occurred
204  }
205 
206 #if DEBUG_PRINT
207  Fw::Logger::logMsg("Wrote:\n");
208  for (U32 byte = 0; byte < writeBuffer.getSize(); byte++) {
209  Fw::Logger::logMsg("0x%02X ",writeBuffer.getData()[byte]);
210 
211  }
212  Fw::Logger::logMsg("\n");
213  Fw::Logger::logMsg("Read:\n");
214  for (U32 byte = 0; byte < readBuffer.getSize(); byte++) {
215  Fw::Logger::logMsg("0x%02X ",readBuffer.getData()[byte]);
216 
217  }
218  Fw::Logger::logMsg("\n");
219 #endif
220 
221  return I2cStatus::I2C_OK;
222  }
223 
224 } // end namespace Drv
#define FW_ASSERT(...)
Definition: Assert.hpp:14
PlatformIntType NATIVE_INT_TYPE
Definition: BasicTypes.h:51
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 logMsg(const char *fmt, POINTER_CAST a0=0, POINTER_CAST a1=0, POINTER_CAST a2=0, POINTER_CAST a3=0, POINTER_CAST a4=0, POINTER_CAST a5=0, POINTER_CAST a6=0, POINTER_CAST a7=0, POINTER_CAST a8=0, POINTER_CAST a9=0)
Definition: Logger.cpp:18
void init()
Object initializer.
Definition: ObjBase.cpp:27