F´ Flight Software - C/C++ Documentation
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 
14 #include <Fw/FPrimeBasicTypes.hpp>
15 #include <Fw/Logger/Logger.hpp>
16 #include "Fw/Types/Assert.hpp"
17 
18 #include <fcntl.h> // required for I2C device configuration
19 #include <linux/i2c-dev.h> // required for constant definitions
20 #include <linux/i2c.h> // required for struct / constant definitions
21 #include <sys/ioctl.h> // required for I2C device usage
22 #include <unistd.h> // required for I2C device access
23 #include <cerrno>
24 
25 namespace Drv {
26 
27 // ----------------------------------------------------------------------
28 // Construction, initialization, and destruction
29 // ----------------------------------------------------------------------
30 
31 LinuxI2cDriver ::LinuxI2cDriver(const char* const compName) : LinuxI2cDriverComponentBase(compName), m_fd(-1) {}
32 
34  if (-1 != this->m_fd) { // check if file is open
35  ::close(this->m_fd);
36  }
37 }
38 
39 bool LinuxI2cDriver::open(const char* device) {
40  FW_ASSERT(device);
41  this->m_fd = ::open(device, O_RDWR);
42  return (-1 != this->m_fd);
43 }
44 
45 // ----------------------------------------------------------------------
46 // Handler implementations for user-defined typed input ports
47 // ----------------------------------------------------------------------
48 
49 // Note this port handler is guarded, so we can make the ioctl call
50 
51 Drv::I2cStatus LinuxI2cDriver ::write_handler(const FwIndexType portNum, U32 addr, Fw::Buffer& serBuffer) {
52  // Make sure file has been opened
53  if (-1 == this->m_fd) {
55  }
56 
57  // select slave address
58  int stat = ioctl(this->m_fd, I2C_SLAVE, addr);
59  if (stat == -1) {
61  }
62  // make sure it isn't a null pointer
63  FW_ASSERT(serBuffer.getData());
64  FW_ASSERT_NO_OVERFLOW(serBuffer.getSize(), size_t);
65  // write data
66  ssize_t status_write = write(this->m_fd, serBuffer.getData(), static_cast<size_t>(serBuffer.getSize()));
67  if (status_write == -1) {
69  }
70  return I2cStatus::I2C_OK;
71 }
72 
73 Drv::I2cStatus LinuxI2cDriver ::read_handler(const FwIndexType portNum, U32 addr, Fw::Buffer& serBuffer) {
74  // Make sure file has been opened
75  if (-1 == this->m_fd) {
77  }
78 
79  // select slave address
80  int stat = ioctl(this->m_fd, I2C_SLAVE, addr);
81  if (stat == -1) {
83  }
84  // make sure it isn't a null pointer
85  FW_ASSERT(serBuffer.getData());
86  // read data
87  FW_ASSERT_NO_OVERFLOW(serBuffer.getSize(), size_t);
88  ssize_t status_read = read(this->m_fd, serBuffer.getData(), static_cast<size_t>(serBuffer.getSize()));
89  if (status_read == -1) {
91  }
92  return I2cStatus::I2C_OK;
93 }
94 
95 Drv::I2cStatus LinuxI2cDriver ::writeRead_handler(const FwIndexType portNum,
96  U32 addr,
97  Fw::Buffer& writeBuffer,
98  Fw::Buffer& readBuffer) {
99  // Make sure file has been opened
100  if (-1 == this->m_fd) {
102  }
103  FW_ASSERT(-1 != this->m_fd);
104 
105  // make sure they are not null pointers
106  FW_ASSERT(writeBuffer.getData());
107  FW_ASSERT(readBuffer.getData());
108  // make sure downcasts are safe
109  FW_ASSERT_NO_OVERFLOW(addr, U16);
110  FW_ASSERT_NO_OVERFLOW(writeBuffer.getSize(), U16);
111  FW_ASSERT_NO_OVERFLOW(readBuffer.getSize(), U16);
112 
113  struct i2c_msg rdwr_msgs[2];
114 
115  // Start address
116  rdwr_msgs[0].addr = static_cast<U16>(addr);
117  rdwr_msgs[0].flags = 0; // write
118  rdwr_msgs[0].len = static_cast<U16>(writeBuffer.getSize());
119  rdwr_msgs[0].buf = writeBuffer.getData();
120 
121  // Read buffer
122  rdwr_msgs[1].addr = static_cast<U16>(addr);
123  rdwr_msgs[1].flags = I2C_M_RD; // read
124  rdwr_msgs[1].len = static_cast<U16>(readBuffer.getSize());
125  rdwr_msgs[1].buf = readBuffer.getData();
126 
127  struct i2c_rdwr_ioctl_data rdwr_data;
128  rdwr_data.msgs = rdwr_msgs;
129  rdwr_data.nmsgs = 2;
130 
131  // Use ioctl to perform the combined write/read transaction
132  int stat = ioctl(this->m_fd, I2C_RDWR, &rdwr_data);
133 
134  if (stat == -1) {
135  // Because we're using ioctl to perform the transaction we dont know exactly the type of error that occurred
137  }
138 
139  return I2cStatus::I2C_OK;
140 }
141 
142 } // end namespace Drv
bool open(const char *device)
U8 * getData() const
Definition: Buffer.cpp:56
LinuxI2cDriver(const char *const compName)
Auto-generated base for LinuxI2cDriver component.
FwSizeType getSize() const
Definition: Buffer.cpp:60
PlatformIndexType FwIndexType
Other errors that don&#39;t fit.
#define FW_ASSERT_NO_OVERFLOW(value, T)
Definition: Assert.hpp:49
I2C driver failed to open device.
Transaction okay.
#define FW_ASSERT(...)
Definition: Assert.hpp:14