#include "pispi.h" #include "piincludes_p.h" #ifndef WINDOWS # include # include # include #endif PRIVATE_DEFINITION_START(PISPI) #ifndef WINDOWS 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) { setPath(path); setSpeed(speed); spi_mode = 0; spi_bits = 8; #ifndef WINDOWS PRIVATE->fd = 0; #endif } void PISPI::setSpeed(uint speed_hz) { spi_speed = speed_hz; } bool PISPI::openDevice() { #ifndef WINDOWS int ret = 0; PRIVATE->fd = ::open(path().dataAscii(), O_RDWR); if (PRIVATE->fd < 0) {piCoutObj << "can't open device";return false;} ret = ioctl(PRIVATE->fd, SPI_IOC_WR_MODE, &spi_mode); if (ret == -1) {piCoutObj << "can't set spi write mode";return false;} ret = ioctl(PRIVATE->fd, SPI_IOC_WR_BITS_PER_WORD, &spi_bits); if (ret == -1) {piCoutObj << "can't set bits per word";return false;} 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 = spi_speed; PRIVATE->spi_ioc_tr.bits_per_word = spi_bits; return true; #else piCoutObj << "PISPI not implemented on windows"; return false; #endif } bool PISPI::closeDevice() { #ifndef WINDOWS 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) { #ifndef WINDOWS 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; ret = ioctl(PRIVATE->fd, SPI_IOC_MESSAGE(1), &PRIVATE->spi_ioc_tr); if (ret < 1) {piCoutObj << "can't send spi message" << ret; return -1;} recv_buf.append(rx_buf); return max_size; } #endif return 0; }