Skip to content
12 changes: 12 additions & 0 deletions Drv/LinuxSpiDriver/Events.fppi
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ event SPI_WriteError(
format "Error writing/reading SPI device {}.{}: {}" \
throttle 5

@ SPI configuration mismatch
event SPI_ConfigMismatch(
device: I32 @< The device
select: I32 @< The chip select
parameter: string @< The parameter being configured
write_value: U32 @< The value written
read_value: U32 @< The value read
) \
severity warning low \
id 3 \
format "SPI device {}.{} configuration mismatch for {}: wrote {}, read {}"

@ SPI open notification
event SPI_PortOpened(
device: I32 @< The device
Expand Down
27 changes: 23 additions & 4 deletions Drv/LinuxSpiDriver/LinuxSpiDriverComponentImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <Fw/FPrimeBasicTypes.hpp>
#include <Fw/Types/Assert.hpp>
#include <Fw/Types/FileNameString.hpp>
#include <Fw/Types/String.hpp>
#include <cerrno>
#include <cstdint>
#include <cstdio>
Expand All @@ -36,6 +37,8 @@
void LinuxSpiDriverComponentImpl::SpiReadWrite_handler(const FwIndexType portNum,
Fw::Buffer& writeBuffer,
Fw::Buffer& readBuffer) {
FW_ASSERT(writeBuffer.getSize() == readBuffer.getSize());

if (this->m_fd == -1) {
return;
}
Expand Down Expand Up @@ -120,12 +123,17 @@
return false;
}

ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
U8 read_mode = 0;
ret = ioctl(fd, SPI_IOC_RD_MODE, &read_mode);
if (ret == -1) {
this->log_WARNING_HI_SPI_ConfigError(device, select, ret);
return false;
}

if (mode != read_mode) {
this->log_WARNING_LO_SPI_ConfigMismatch(device, select, Fw::String("MODE"), mode, read_mode);
}

/*
* 8 bits per word
*/
Expand All @@ -136,27 +144,38 @@
return false;
}

ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
U8 read_bits = 0;
ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &read_bits);
if (ret == -1) {
this->log_WARNING_HI_SPI_ConfigError(device, select, ret);
return false;
}

if (bits != read_bits) {
this->log_WARNING_LO_SPI_ConfigMismatch(device, select, Fw::String("BITS_PER_WORD"), bits, read_bits);
}

/*
* Max speed in Hz
*/
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &clock);
SpiFrequency write_clock = clock;
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &write_clock);
if (ret == -1) {
this->log_WARNING_HI_SPI_ConfigError(device, select, ret);
return false;
}

ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &clock);
SpiFrequency read_clock;
ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &read_clock);
if (ret == -1) {
this->log_WARNING_HI_SPI_ConfigError(device, select, ret);
return false;
}

if (clock != read_clock) {
this->log_WARNING_LO_SPI_ConfigMismatch(device, select, Fw::String("MAX_SPEED_HZ"), clock, read_clock);
}

return true;
}

Expand Down
Loading