F´ Flight Software - C/C++ Documentation devel
A framework for building embedded system applications to NASA flight quality standards.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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
42 void LinuxI2cDriver ::
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 }
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 = 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 = 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.
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