Forked from
Berkeley Lab / labRemote
332 commits behind the upstream repository.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
SPIDevCom.cpp 3.29 KiB
#include "SPIDevCom.h"
#include <linux/spi/spidev.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <cstring>
#include "ComIOException.h"
SPIDevCom::SPIDevCom(const std::string& spidev)
: SPICom()
{
m_fh = open(spidev.c_str(), O_RDWR);
if(m_fh<0)
throw ComIOException(std::string("SPIDevCom open failed: ")+std::strerror(errno));
}
SPIDevCom::~SPIDevCom()
{ }
void SPIDevCom::write_reg32(uint32_t address, uint32_t data)
{
write_block(address,
{static_cast<uint8_t>((data>>24)&0xFF),
static_cast<uint8_t>((data>>16)&0xFF),
static_cast<uint8_t>((data>> 8)&0xFF),
static_cast<uint8_t>((data>> 0)&0xFF)});
}
void SPIDevCom::write_reg16(uint32_t address, uint16_t data)
{
write_block(address,
{static_cast<uint8_t>((data>> 8)&0xFF),
static_cast<uint8_t>((data>> 0)&0xFF)});
}
void SPIDevCom::write_reg8 (uint32_t address, uint8_t data)
{
write_block(address,{data});
}
void SPIDevCom::write_reg32(uint32_t data)
{
write_block({static_cast<uint8_t>((data>>24)&0xFF),
static_cast<uint8_t>((data>>16)&0xFF),
static_cast<uint8_t>((data>> 8)&0xFF),
static_cast<uint8_t>((data>> 0)&0xFF)});
}
void SPIDevCom::write_reg16(uint16_t data)
{
write_block({static_cast<uint8_t>((data>> 8)&0xFF),
static_cast<uint8_t>((data>> 0)&0xFF)});
}
void SPIDevCom::write_reg8 (uint8_t data)
{
write_block({data});
}
void SPIDevCom::write_block(uint32_t address, const std::vector<uint8_t>& data)
{
std::vector<uint8_t> inbuf=data;
inbuf.insert(inbuf.begin(),static_cast<uint8_t>(address&0xFF));
write_block(inbuf);
}
void SPIDevCom::write_block(const std::vector<uint8_t>& data)
{
struct spi_ioc_transfer msgs[1];
memset(msgs, 0, sizeof msgs);
msgs[0].tx_buf = (unsigned long)&data[0];
msgs[0].len = data.size();
if (ioctl(m_fh, SPI_IOC_MESSAGE(1), &msgs) < 0)
throw ComIOException(std::string("SPIDevCom write_block failed: ")+std::strerror(errno));
}
uint32_t SPIDevCom::read_reg32(uint32_t address)
{
write_reg8(address&0xFF);
return read_reg32();
}
uint32_t SPIDevCom::read_reg24(uint32_t address)
{
write_reg8(address&0xFF);
return read_reg24();
}
uint16_t SPIDevCom::read_reg16(uint32_t address)
{
write_reg8(address&0xFF);
return read_reg16();
}
uint8_t SPIDevCom::read_reg8 (uint32_t address)
{
write_reg8(address&0xFF);
return read_reg8();
}
uint32_t SPIDevCom::read_reg32()
{
std::vector<uint8_t> data(4);
read_block(data);
return (data[0]<<24|data[1]<<16|data[2]<<8|data[3]);
}
uint32_t SPIDevCom::read_reg24()
{
std::vector<uint8_t> data(3);
read_block(data);
return (data[0]<<16|data[1]<<8|data[2]);
}
uint16_t SPIDevCom::read_reg16()
{
std::vector<uint8_t> data(2);
read_block(data);
return (data[0]<<8|data[1]);
}
uint8_t SPIDevCom::read_reg8 ()
{
std::vector<uint8_t> data(1);
read_block(data);
return data[0];
}
void SPIDevCom::read_block(uint32_t address, std::vector<uint8_t>& data)
{
write_reg8(address&0xFF);
read_block(data);
}
void SPIDevCom::read_block(std::vector<uint8_t>& data)
{
struct spi_ioc_transfer msgs[1];
memset(msgs, 0, sizeof msgs);
msgs[0].rx_buf =(unsigned long)&data[0];
msgs[0].len = data.size();
if (ioctl(m_fh, SPI_IOC_MESSAGE(1), &msgs) < 0)
throw ComIOException(std::string("SPIDevCom read_block failed: ")+std::strerror(errno));
}