F´ Flight Software - C/C++ Documentation devel
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
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