mirror of
https://github.com/nasa/fprime.git
synced 2025-12-10 17:47:10 -06:00
* lestarch: adding logical types implementation into Linux/StandardTypes.hpp * lestarch: removing VxWorks StandardTypes from repository * updated fprime types for correct compilation with vxworks and baremetal * lestarch: refactoring types and configuration header w.r.t type design * lestarch: replacing usages of AssertArg with FwAssertArgType * lestarch: missspelled configuration * lestarch: minor compilation fixes * lestarch: renaming StandardTypes.hpp -> PlatformTypes.hpp * lestarch: updating PRI tokens * lestarch: replacing BasicTypes.hpp includes with FpConfig.hpp * lestarch: UT and compilation fixes for types refactor * lestarch: sp * lestarch: fixing RPI issues in PassiveConsoleTextLogger * lestarch: converting RPI build to debug * lestarch: removing duplicate config imports * lestarch: fixing documentation * lestarch: fixing up multiple definitions and RPI compilation problems * lestarch: reverting debug build * lestarch: reverting platform types to class-based constants * lestarch: reworking basic types * lestarch: configured types refactor into classes * lestarch: fixing bugs with static constants in classes * lestarch: fixing platform types spelling and documentation * lestarch: adding include guards to types headers Co-authored-by: Kevin F Ortega <kevin.f.ortega@jpl.nasa.gov>
227 lines
6.2 KiB
C++
227 lines
6.2 KiB
C++
// ======================================================================
|
|
// \title LinuxI2cDriverComponentImpl.cpp
|
|
// \author tcanham
|
|
// \brief cpp file for LinuxI2cDriver component implementation class
|
|
//
|
|
// \copyright
|
|
// Copyright 2009-2015, by the California Institute of Technology.
|
|
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
|
// acknowledged.
|
|
//
|
|
// ======================================================================
|
|
|
|
#include "Fw/Types/Assert.hpp"
|
|
#include <FpConfig.hpp>
|
|
#include <Drv/LinuxI2cDriver/LinuxI2cDriver.hpp>
|
|
#include <Fw/Logger/Logger.hpp>
|
|
|
|
#include <unistd.h> // required for I2C device access
|
|
#include <fcntl.h> // required for I2C device configuration
|
|
#include <sys/ioctl.h> // required for I2C device usage
|
|
#include <linux/i2c.h> // required for struct / constant definitions
|
|
#include <linux/i2c-dev.h> // required for constant definitions
|
|
#include <cerrno>
|
|
|
|
#define DEBUG_PRINT 0
|
|
|
|
namespace Drv {
|
|
|
|
// ----------------------------------------------------------------------
|
|
// Construction, initialization, and destruction
|
|
// ----------------------------------------------------------------------
|
|
|
|
LinuxI2cDriver ::
|
|
LinuxI2cDriver(
|
|
const char *const compName
|
|
) : LinuxI2cDriverComponentBase(compName),
|
|
m_fd(-1)
|
|
{
|
|
|
|
}
|
|
|
|
void LinuxI2cDriver ::
|
|
init(
|
|
const NATIVE_INT_TYPE instance
|
|
)
|
|
{
|
|
LinuxI2cDriverComponentBase::init(instance);
|
|
}
|
|
|
|
LinuxI2cDriver::
|
|
~LinuxI2cDriver()
|
|
{
|
|
if (-1 != this->m_fd) { // check if file is open
|
|
::close(this->m_fd);
|
|
}
|
|
}
|
|
|
|
bool LinuxI2cDriver::open(const char* device) {
|
|
FW_ASSERT(device);
|
|
this->m_fd = ::open(device, O_RDWR);
|
|
return (-1 != this->m_fd);
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------------------
|
|
// Handler implementations for user-defined typed input ports
|
|
// ----------------------------------------------------------------------
|
|
|
|
// Note this port handler is guarded, so we can make the ioctl call
|
|
|
|
Drv::I2cStatus LinuxI2cDriver ::
|
|
write_handler(
|
|
const NATIVE_INT_TYPE portNum,
|
|
U32 addr,
|
|
Fw::Buffer &serBuffer
|
|
)
|
|
{
|
|
// Make sure file has been opened
|
|
if (-1 == this->m_fd) {
|
|
return I2cStatus::I2C_OPEN_ERR;
|
|
}
|
|
|
|
#if DEBUG_PRINT
|
|
Fw::Logger::logMsg("I2c addr: 0x%02X\n",addr);
|
|
for (U32 byte = 0; byte < serBuffer.getSize(); byte++) {
|
|
Fw::Logger::logMsg("0x%02X ",serBuffer.getData()[byte]);
|
|
|
|
}
|
|
Fw::Logger::logMsg("\n");
|
|
#endif
|
|
// select slave address
|
|
int stat = ioctl(this->m_fd, I2C_SLAVE, addr);
|
|
if (stat == -1) {
|
|
#if DEBUG_PRINT
|
|
Fw::Logger::logMsg("Status: %d Errno: %d\n", stat, errno);
|
|
#endif
|
|
return I2cStatus::I2C_ADDRESS_ERR;
|
|
}
|
|
// make sure it isn't a null pointer
|
|
FW_ASSERT(serBuffer.getData());
|
|
// write data
|
|
stat = write(this->m_fd, serBuffer.getData(), serBuffer.getSize());
|
|
if (stat == -1) {
|
|
#if DEBUG_PRINT
|
|
Fw::Logger::logMsg("Status: %d Errno: %d\n", stat, errno);
|
|
#endif
|
|
return I2cStatus::I2C_WRITE_ERR;
|
|
}
|
|
return I2cStatus::I2C_OK;
|
|
}
|
|
|
|
Drv::I2cStatus LinuxI2cDriver ::
|
|
read_handler(
|
|
const NATIVE_INT_TYPE portNum,
|
|
U32 addr,
|
|
Fw::Buffer &serBuffer
|
|
)
|
|
{
|
|
// Make sure file has been opened
|
|
if (-1 == this->m_fd) {
|
|
return I2cStatus::I2C_OPEN_ERR;
|
|
}
|
|
|
|
#if DEBUG_PRINT
|
|
Fw::Logger::logMsg("I2c addr: 0x%02X\n",addr);
|
|
#endif
|
|
// select slave address
|
|
int stat = ioctl(this->m_fd, I2C_SLAVE, addr);
|
|
if (stat == -1) {
|
|
#if DEBUG_PRINT
|
|
Fw::Logger::logMsg("Status: %d Errno: %d\n", stat, errno);
|
|
#endif
|
|
return I2cStatus::I2C_ADDRESS_ERR;
|
|
}
|
|
// make sure it isn't a null pointer
|
|
FW_ASSERT(serBuffer.getData());
|
|
// read data
|
|
stat = read(this->m_fd, serBuffer.getData(), serBuffer.getSize());
|
|
if (stat == -1) {
|
|
#if DEBUG_PRINT
|
|
Fw::Logger::logMsg("Status: %d Errno: %d\n", stat, errno);
|
|
#endif
|
|
return I2cStatus::I2C_READ_ERR;
|
|
}
|
|
#if DEBUG_PRINT
|
|
for (U32 byte = 0; byte < serBuffer.getSize(); byte++) {
|
|
Fw::Logger::logMsg("0x%02X ",serBuffer.getData()[byte]);
|
|
|
|
}
|
|
Fw::Logger::logMsg("\n");
|
|
#endif
|
|
return I2cStatus::I2C_OK;
|
|
}
|
|
|
|
Drv::I2cStatus LinuxI2cDriver ::
|
|
writeRead_handler(
|
|
const NATIVE_INT_TYPE portNum, /*!< The port number*/
|
|
U32 addr,
|
|
Fw::Buffer &writeBuffer,
|
|
Fw::Buffer &readBuffer
|
|
){
|
|
|
|
// Make sure file has been opened
|
|
if (-1 == this->m_fd) {
|
|
return I2cStatus::I2C_OPEN_ERR;
|
|
}
|
|
FW_ASSERT(-1 != this->m_fd);
|
|
|
|
// make sure they are not null pointers
|
|
FW_ASSERT(writeBuffer.getData());
|
|
FW_ASSERT(readBuffer.getData());
|
|
|
|
#if DEBUG_PRINT
|
|
Fw::Logger::logMsg("I2c addr: 0x%02X\n",addr);
|
|
#endif
|
|
|
|
struct i2c_msg rdwr_msgs[2] = {
|
|
{ // Start address
|
|
.addr = static_cast<U16>(addr),
|
|
.flags = 0, // write
|
|
.len = static_cast<U16>(writeBuffer.getSize()),
|
|
.buf = writeBuffer.getData()
|
|
},
|
|
{ // Read buffer
|
|
.addr = static_cast<U16>(addr),
|
|
.flags = I2C_M_RD, // read
|
|
.len = static_cast<U16>(readBuffer.getSize()),
|
|
.buf = readBuffer.getData()
|
|
}
|
|
};
|
|
|
|
struct i2c_rdwr_ioctl_data rdwr_data = {
|
|
.msgs = rdwr_msgs,
|
|
.nmsgs = 2
|
|
};
|
|
|
|
//Use ioctl to perform the combined write/read transaction
|
|
NATIVE_INT_TYPE stat = ioctl(this->m_fd, I2C_RDWR, &rdwr_data);
|
|
|
|
if(stat == -1){
|
|
#if DEBUG_PRINT
|
|
Fw::Logger::logMsg("Status: %d Errno: %d\n", stat, errno);
|
|
#endif
|
|
//Because we're using ioctl to perform the transaction we dont know exactly the type of error that occurred
|
|
return I2cStatus::I2C_OTHER_ERR;
|
|
}
|
|
|
|
#if DEBUG_PRINT
|
|
Fw::Logger::logMsg("Wrote:\n");
|
|
for (U32 byte = 0; byte < writeBuffer.getSize(); byte++) {
|
|
Fw::Logger::logMsg("0x%02X ",writeBuffer.getData()[byte]);
|
|
|
|
}
|
|
Fw::Logger::logMsg("\n");
|
|
Fw::Logger::logMsg("Read:\n");
|
|
for (U32 byte = 0; byte < readBuffer.getSize(); byte++) {
|
|
Fw::Logger::logMsg("0x%02X ",readBuffer.getData()[byte]);
|
|
|
|
}
|
|
Fw::Logger::logMsg("\n");
|
|
#endif
|
|
|
|
return I2cStatus::I2C_OK;
|
|
}
|
|
|
|
} // end namespace Drv
|