Skip to content
Snippets Groups Projects
Commit 15a07194 authored by Karol Krizka's avatar Karol Krizka
Browse files

Add SPIDevCom implementation of spidev userpace linux driver.

parent 7755f6f4
No related branches found
No related tags found
No related merge requests found
#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 <iomanip>
#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_reg32 failed: ")+std::strerror(errno));
}
uint32_t SPIDevCom::read_reg32(uint32_t address)
{
write_reg8(address&0xFF);
return read_reg32();
}
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]);
}
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_reg16 failed: ")+std::strerror(errno));
}
#ifndef SPIDEVCOM_H
#define SPIDEVCOM_H
#include "SPICom.h"
class SPIDevCom : public SPICom
{
public:
SPIDevCom(const std::string& spidev);
virtual ~SPIDevCom();
//
// Write commands
virtual void write_reg32(uint32_t address, uint32_t data);
virtual void write_reg16(uint32_t address, uint16_t data);
virtual void write_reg8 (uint32_t address, uint8_t data);
virtual void write_reg32(uint32_t data);
virtual void write_reg16(uint16_t data);
virtual void write_reg8 (uint8_t data);
virtual void write_block(uint32_t address, const std::vector<uint8_t>& data);
virtual void write_block(const std::vector<uint8_t>& data);
//
// Read commands
virtual uint32_t read_reg32(uint32_t address);
virtual uint16_t read_reg16(uint32_t address);
virtual uint8_t read_reg8 (uint32_t address);
virtual uint32_t read_reg32();
virtual uint16_t read_reg16();
virtual uint8_t read_reg8 ();
virtual void read_block(uint32_t address, std::vector<uint8_t>& data);
virtual void read_block(std::vector<uint8_t>& data);
private:
int m_fh =0;
};
#endif // SPIDEVCOM_H
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment