F´ Flight Software - C/C++ Documentation NASA-v1.6.0
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 {
47 LinuxI2cDriverComponentBase::init(instance);
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) {
80 return I2cStatus::I2C_OPEN_ERR;
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
97 return I2cStatus::I2C_ADDRESS_ERR;
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
107 return I2cStatus::I2C_WRITE_ERR;
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) {
121 return I2cStatus::I2C_OPEN_ERR;
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
133 return I2cStatus::I2C_ADDRESS_ERR;
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
143 return I2cStatus::I2C_READ_ERR;
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) {
165 return I2cStatus::I2C_OPEN_ERR;
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 { // Start address
179 .addr = static_cast<U16>(addr),
180 .flags = 0, // write
181 .len = static_cast<U16>(writeBuffer.getSize()),
182 .buf = writeBuffer.getData()
183 },
184 { // Read buffer
185 .addr = static_cast<U16>(addr),
186 .flags = I2C_M_RD, // read
187 .len = static_cast<U16>(readBuffer.getSize()),
188 .buf = readBuffer.getData()
189 }
190 };
191
192 struct i2c_rdwr_ioctl_data rdwr_data = {
193 .msgs = rdwr_msgs,
194 .nmsgs = 2
195 };
196
197 //Use ioctl to perform the combined write/read transaction
198 NATIVE_INT_TYPE stat = ioctl(this->m_fd, I2C_RDWR, &rdwr_data);
199
200 if(stat == -1){
201 #if DEBUG_PRINT
202 Fw::Logger::logMsg("Status: %d Errno: %d\n", stat, errno);
203 #endif
204 //Because we're using ioctl to perform the transaction we dont know exactly the type of error that occurred
205 return I2cStatus::I2C_OTHER_ERR;
206 }
207
208#if DEBUG_PRINT
209 Fw::Logger::logMsg("Wrote:\n");
210 for (U32 byte = 0; byte < writeBuffer.getSize(); byte++) {
211 Fw::Logger::logMsg("0x%02X ",writeBuffer.getData()[byte]);
212
213 }
214 Fw::Logger::logMsg("\n");
215 Fw::Logger::logMsg("Read:\n");
216 for (U32 byte = 0; byte < readBuffer.getSize(); byte++) {
217 Fw::Logger::logMsg("0x%02X ",readBuffer.getData()[byte]);
218
219 }
220 Fw::Logger::logMsg("\n");
221#endif
222
223 return I2cStatus::I2C_OK;
224 }
225
226} // end namespace Drv
#define FW_ASSERT(...)
Definition Assert.hpp:7
PlatformIntType NATIVE_INT_TYPE
Definition BasicTypes.h:51
C++-compatible configuration header for fprime configuration.
bool open(const char *device)
U8 * getData() const
Definition Buffer.cpp:60
U32 getSize() const
Definition Buffer.cpp:64
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