Files
pip/src_main/io_devices/pispi.cpp
Бычков Андрей 283da5b602 FreeRTOS console and io devices support for compile
git-svn-id: svn://db.shs.com.ru/pip@688 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5
2019-02-06 13:04:25 +00:00

169 lines
4.6 KiB
C++

#include "pispi.h"
#include "pipropertystorage.h"
#include "piincludes_p.h"
#ifdef LINUX
# define PIP_SPI
#endif
#ifdef PIP_SPI
# include <fcntl.h>
# include <sys/ioctl.h>
# include <linux/spi/spidev.h>
#endif
PRIVATE_DEFINITION_START(PISPI)
#ifdef PIP_SPI
int fd;
spi_ioc_transfer spi_ioc_tr;
#endif
PRIVATE_DEFINITION_END(PISPI)
REGISTER_DEVICE(PISPI)
PISPI::PISPI(const PIString & path, uint speed, PIIODevice::DeviceMode mode) : PIIODevice(path, mode) {
setThreadedReadBufferSize(1024);
setPath(path);
setSpeed(speed);
setBits(8);
spi_mode = 0;
if (mode == ReadOnly)
piCoutObj << "error, SPI can't work in ReadOnly mode";
#ifdef PIP_SPI
PRIVATE->fd = 0;
#endif
}
void PISPI::setSpeed(uint speed_hz) {
spi_speed = speed_hz;
}
void PISPI::setBits(uchar bits) {
spi_bits = bits;
}
void PISPI::setParameter(PISPI::Parameters parameter, bool on) {
PIFlags<Parameters> cp = (PIFlags<Parameters>)spi_mode;
cp.setFlag(parameter, on);
spi_mode = (int)cp;
}
bool PISPI::isParameterSet(PISPI::Parameters parameter) const {
PIFlags<Parameters> cp = (PIFlags<Parameters>)spi_mode;
return cp[parameter];
}
bool PISPI::openDevice() {
#ifdef PIP_SPI
int ret = 0;
//piCoutObj << "open device" << path();
PRIVATE->fd = ::open(path().dataAscii(), O_RDWR);
if (PRIVATE->fd < 0) {piCoutObj << "can't open device";return false;}
//piCoutObj << "set mode" << spi_mode;
ret = ioctl(PRIVATE->fd, SPI_IOC_WR_MODE, &spi_mode);
if (ret == -1) {piCoutObj << "can't set spi write mode";return false;}
//piCoutObj << "set bits" << spi_bits;
ret = ioctl(PRIVATE->fd, SPI_IOC_WR_BITS_PER_WORD, &spi_bits);
if (ret == -1) {piCoutObj << "can't set bits per word";return false;}
//piCoutObj << "set speed" << spi_speed;
ret = ioctl(PRIVATE->fd, SPI_IOC_WR_MAX_SPEED_HZ, &spi_speed);
if (ret == -1) {piCoutObj << "can't set max write speed hz";return false;}
piCoutObj << "SPI open" << path() << "speed:" << spi_speed/1000 << "KHz" << "mode" << spi_mode << "bits" << spi_bits;
PRIVATE->spi_ioc_tr.delay_usecs = 0;
PRIVATE->spi_ioc_tr.speed_hz = 0;
PRIVATE->spi_ioc_tr.bits_per_word = spi_bits;
return true;
#else
piCoutObj << "PISPI not implemented on windows";
return false;
#endif
}
bool PISPI::closeDevice() {
#ifdef PIP_SPI
if (PRIVATE->fd) ::close(PRIVATE->fd);
#endif
return true;
}
int PISPI::readDevice(void * read_to, int max_size) {
int sz = piMini(recv_buf.size_s(), max_size);
memcpy(read_to, recv_buf.data(), sz);
recv_buf.resize(recv_buf.size_s() - sz);
return sz;
}
int PISPI::writeDevice(const void * data, int max_size) {
#ifdef PIP_SPI
if (max_size > 0) {
if (tx_buf.size_s() != max_size) {
tx_buf.resize(max_size);
rx_buf.resize(max_size);
PRIVATE->spi_ioc_tr.tx_buf = (ulong)(tx_buf.data());
PRIVATE->spi_ioc_tr.rx_buf = (ulong)(rx_buf.data());
PRIVATE->spi_ioc_tr.len = max_size;
}
memcpy(tx_buf.data(), data, max_size);
int ret;
//piCoutObj << "write" << max_size << tx_buf.size();
ret = ioctl(PRIVATE->fd, SPI_IOC_MESSAGE(1), &PRIVATE->spi_ioc_tr);
if (ret < 1) {piCoutObj << "can't send spi message" << ret; return -1;}
if (canRead()) recv_buf.append(rx_buf);
if (recv_buf.size_s() > threadedReadBufferSize()) recv_buf.resize(threadedReadBufferSize());
return max_size;
}
#endif
return 0;
}
PIString PISPI::constructFullPathDevice() const {
PIString ret;
ret << path() << ":" << int(speed()) << ":" << int(bits()) << ":" << (int)parameters();
return ret;
}
void PISPI::configureFromFullPathDevice(const PIString & full_path) {
PIStringList pl = full_path.split(":");
for (int i = 0; i < pl.size_s(); ++i) {
PIString p(pl[i]);
switch (i) {
case 0: setPath(p); break;
case 1: setSpeed(p.toInt()); break;
case 2: setBits(p.toInt()); break;
case 3: setParameters(p.toInt()); break;
default: break;
}
}
}
PIPropertyStorage PISPI::constructVariantDevice() const {
PIPropertyStorage ret;
ret.addProperty("path", path());
ret.addProperty("speed", int(speed()));
ret.addProperty("bits", int(bits()));
ret.addProperty("clock inverse", isParameterSet(ClockInverse));
ret.addProperty("clock phase shift", isParameterSet(ClockPhaseShift));
return ret;
}
void PISPI::configureFromVariantDevice(const PIPropertyStorage & d) {
setPath(d.propertyValueByName("path").toString());
setSpeed(d.propertyValueByName("speed").toInt());
setBits(d.propertyValueByName("bits").toInt());
setParameter(ClockInverse, d.propertyValueByName("clock inverse").toBool());
setParameter(ClockPhaseShift, d.propertyValueByName("clock phase shift").toBool());
}