fprime/Drv/LinuxSpiDriver/LinuxSpiDriverComponentImpl.cpp
M Starch b76d8c9a0c
Update/types refactor as constants (#1623)
* 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>
2022-08-18 13:25:56 -07:00

176 lines
5.8 KiB
C++

// ======================================================================
// \title LinuxSpiDriverImpl.cpp
// \author tcanham
// \brief cpp file for LinuxSpiDriver component implementation class
//
// \copyright
// Copyright 2009-2015, by the California Institute of Technology.
// ALL RIGHTS RESERVED. United States Government Sponsorship
// acknowledged.
//
// ======================================================================
#include <Drv/LinuxSpiDriver/LinuxSpiDriverComponentImpl.hpp>
#include <FpConfig.hpp>
#include <Fw/Types/Assert.hpp>
#include <cstdint>
#include <unistd.h>
#include <cstdio>
#include <cstdlib>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#include <cerrno>
//#define DEBUG_PRINT(x,...) printf(x,##__VA_ARGS__); fflush(stdout)
#define DEBUG_PRINT(x,...)
namespace Drv {
// ----------------------------------------------------------------------
// Handler implementations for user-defined typed input ports
// ----------------------------------------------------------------------
void LinuxSpiDriverComponentImpl::SpiReadWrite_handler(
const NATIVE_INT_TYPE portNum, Fw::Buffer &writeBuffer,
Fw::Buffer &readBuffer) {
if (this->m_fd == -1) {
return;
}
DEBUG_PRINT("Writing %d bytes to SPI\n",writeBuffer.getSize());
spi_ioc_transfer tr;
// Zero for unused fields:
memset(&tr, 0, sizeof(tr));
tr.tx_buf = reinterpret_cast<U64>(writeBuffer.getData());
tr.rx_buf = reinterpret_cast<U64>(readBuffer.getData());
tr.len = writeBuffer.getSize();
/*
.speed_hz = 0,
.delay_usecs = 0,
.bits_per_word = 0,
.cs_change = 0,
.tx_nbits = 0, // on more-recent kernel versions;
.rx_nbits = 0, // on more-recent kernel versions;
.pad = 0
*/
NATIVE_INT_TYPE stat = ioctl(this->m_fd, SPI_IOC_MESSAGE(1), &tr);
if (stat < 1) {
this->log_WARNING_HI_SPI_WriteError(this->m_device,this->m_select,stat);
}
this->m_bytes += readBuffer.getSize();
this->tlmWrite_SPI_Bytes(this->m_bytes);
return;
}
bool LinuxSpiDriverComponentImpl::open(NATIVE_INT_TYPE device,
NATIVE_INT_TYPE select,
SpiFrequency clock) {
this->m_device = device;
this->m_select = select;
NATIVE_INT_TYPE fd;
NATIVE_INT_TYPE ret;
// Open:
char devName[256];
snprintf(devName,sizeof(devName),"/dev/spidev%d.%d",device,select);
// null terminate
devName[sizeof(devName)-1] = 0;
DEBUG_PRINT("Opening SPI device %s\n",devName);
fd = ::open(devName, O_RDWR);
if (fd == -1) {
DEBUG_PRINT("open SPI device %d.%d failed. %d\n",device,select,errno);
this->log_WARNING_HI_SPI_OpenError(device,select,fd);
return false;
} else {
DEBUG_PRINT("Successfully opened SPI device %s fd %d\n",devName,fd);
}
this->m_fd = fd;
// Configure:
/*
* SPI Mode 0
*/
U8 mode = SPI_MODE_0; // Mode 0 (CPOL = 0, CPHA = 0)
ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
if (ret == -1) {
DEBUG_PRINT("ioctl SPI_IOC_WR_MODE fd %d failed. %d\n",fd,errno);
this->log_WARNING_HI_SPI_ConfigError(device,select,ret);
return false;
} else {
DEBUG_PRINT("SPI fd %d WR mode successfully configured to %d\n",fd,mode);
}
ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
if (ret == -1) {
DEBUG_PRINT("ioctl SPI_IOC_RD_MODE fd %d failed. %d\n",fd,errno);
this->log_WARNING_HI_SPI_ConfigError(device,select,ret);
return false;
} else {
DEBUG_PRINT("SPI fd %d RD mode successfully configured to %d\n",fd,mode);
}
/*
* 8 bits per word
*/
U8 bits = 8;
ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
if (ret == -1) {
DEBUG_PRINT("ioctl SPI_IOC_WR_BITS_PER_WORD fd %d failed. %d\n",fd,errno);
this->log_WARNING_HI_SPI_ConfigError(device,select,ret);
return false;
} else {
DEBUG_PRINT("SPI fd %d WR bits per word successfully configured to %d\n",fd,bits);
}
ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
if (ret == -1) {
DEBUG_PRINT("ioctl SPI_IOC_RD_BITS_PER_WORD fd %d failed. %d\n",fd,errno);
this->log_WARNING_HI_SPI_ConfigError(device,select,ret);
return false;
} else {
DEBUG_PRINT("SPI fd %d RD bits per word successfully configured to %d\n",fd,bits);
}
/*
* Max speed in Hz
*/
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &clock);
if (ret == -1) {
DEBUG_PRINT("ioctl SPI_IOC_WR_MAX_SPEED_HZ fd %d failed. %d\n",fd,errno);
this->log_WARNING_HI_SPI_ConfigError(device,select,ret);
return false;
} else {
DEBUG_PRINT("SPI fd %d WR freq successfully configured to %d\n",fd,clock);
}
ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &clock);
if (ret == -1) {
DEBUG_PRINT("ioctl SPI_IOC_RD_MAX_SPEED_HZ fd %d failed. %d\n",fd,errno);
this->log_WARNING_HI_SPI_ConfigError(device,select,ret);
return false;
} else {
DEBUG_PRINT("SPI fd %d RD freq successfully configured to %d\n",fd,clock);
}
return true;
}
LinuxSpiDriverComponentImpl::~LinuxSpiDriverComponentImpl() {
DEBUG_PRINT("Closing SPI device %d\n",this->m_fd);
(void) close(this->m_fd);
}
} // end namespace Drv