F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
Loading...
Searching...
No Matches
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
27namespace Drv {
28
29 // ----------------------------------------------------------------------
30 // Construction, initialization, and destruction
31 // ----------------------------------------------------------------------
32
33 LinuxI2cDriver ::
34 LinuxI2cDriver(
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.
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