Commit e234ba71 authored by plasticassius's avatar plasticassius Committed by GitHub

fix SPIDEV interface (#315)

* fix SPIDEV interface
* cleanup SPIDEV
parent ab738fdf
...@@ -10,36 +10,33 @@ ...@@ -10,36 +10,33 @@
#include "spi.h" #include "spi.h"
#include <pthread.h> #include <fcntl.h>
static pthread_mutex_t spiMutex; #include <linux/spi/spidev.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <unistd.h>
#define RF24_SPIDEV_BITS 8
SPI::SPI():fd(-1) { SPI::SPI():fd(-1) {
} }
void SPI::begin(int busNo){ void SPI::begin(int busNo){
this->device = "/dev/spidev0.0";
/* set spidev accordingly to busNo like: /* set spidev accordingly to busNo like:
* busNo = 23 -> /dev/spidev2.3 * busNo = 23 -> /dev/spidev2.3
* *
* a bit messy but simple * a bit messy but simple
* */ * */
this->device[11] += (busNo / 10) % 10; char device[] = "/dev/spidev0.0";
this->device[13] += busNo % 10; device[11] += (busNo / 10) % 10;
this->bits = 8; device[13] += busNo % 10;
this->speed = RF24_SPIDEV_SPEED;
this->mode=0;
//this->mode |= SPI_NO_CS;
this->init();
}
void SPI::init()
{
int ret;
if (this->fd < 0) // check whether spi is already open if (this->fd < 0) // check whether spi is already open
{ {
this->fd = open(this->device.c_str(), O_RDWR); this->fd = open(device, O_RDWR);
if (this->fd < 0) if (this->fd < 0)
{ {
...@@ -48,17 +45,27 @@ void SPI::init() ...@@ -48,17 +45,27 @@ void SPI::init()
} }
} }
init();
}
void SPI::init()
{
uint8_t bits = RF24_SPIDEV_BITS;
uint32_t speed = RF24_SPIDEV_SPEED;
uint8_t mode = 0;
int ret;
/* /*
* spi mode * spi mode
*/ */
ret = ioctl(this->fd, SPI_IOC_WR_MODE, &this->mode); ret = ioctl(this->fd, SPI_IOC_WR_MODE, &mode);
if (ret == -1) if (ret == -1)
{ {
perror("can't set spi mode"); perror("can't set spi mode");
abort(); abort();
} }
ret = ioctl(this->fd, SPI_IOC_RD_MODE, &this->mode); ret = ioctl(this->fd, SPI_IOC_RD_MODE, &mode);
if (ret == -1) if (ret == -1)
{ {
perror("can't set spi mode"); perror("can't set spi mode");
...@@ -68,14 +75,14 @@ void SPI::init() ...@@ -68,14 +75,14 @@ void SPI::init()
/* /*
* bits per word * bits per word
*/ */
ret = ioctl(this->fd, SPI_IOC_WR_BITS_PER_WORD, &this->bits); ret = ioctl(this->fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
if (ret == -1) if (ret == -1)
{ {
perror("can't set bits per word"); perror("can't set bits per word");
abort(); abort();
} }
ret = ioctl(this->fd, SPI_IOC_RD_BITS_PER_WORD, &this->bits); ret = ioctl(this->fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
if (ret == -1) if (ret == -1)
{ {
perror("can't set bits per word"); perror("can't set bits per word");
...@@ -84,14 +91,14 @@ void SPI::init() ...@@ -84,14 +91,14 @@ void SPI::init()
/* /*
* max speed hz * max speed hz
*/ */
ret = ioctl(this->fd, SPI_IOC_WR_MAX_SPEED_HZ, &this->speed); ret = ioctl(this->fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
if (ret == -1) if (ret == -1)
{ {
perror("can't set max speed hz"); perror("can't set max speed hz");
abort(); abort();
} }
ret = ioctl(this->fd, SPI_IOC_RD_MAX_SPEED_HZ, &this->speed); ret = ioctl(this->fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
if (ret == -1) if (ret == -1)
{ {
perror("can't set max speed hz"); perror("can't set max speed hz");
...@@ -99,102 +106,52 @@ void SPI::init() ...@@ -99,102 +106,52 @@ void SPI::init()
} }
} }
uint8_t SPI::transfer(uint8_t tx_) uint8_t SPI::transfer(uint8_t tx)
{ {
pthread_mutex_lock (&spiMutex);
int ret;
uint8_t tx[1] = {tx_};
uint8_t rx[1];
this->init();
struct spi_ioc_transfer tr = {
tr.tx_buf = (unsigned long)&tx[0],
tr.rx_buf = (unsigned long)&rx[0],
tr.len = 1,//ARRAY_SIZE(tx),
tr.delay_usecs = 0,
tr.cs_change=1,
tr.bits_per_word = this->bits,
};
tr.speed_hz = this->speed,
//Note: On RPi, for some reason I started getting 'bad message' errors, and changing the struct as below fixed it, until an update...??
//
/* // One byte is transfered at once
uint8_t rx[ARRAY_SIZE(tx)] = {0};
struct spi_ioc_transfer tr; struct spi_ioc_transfer tr;
tr.tx_buf = (unsigned long)tx; memset(&tr, 0, sizeof(tr));
tr.rx_buf = (unsigned long)rx; tr.tx_buf = (unsigned long)&tx;
tr.len = ARRAY_SIZE(tx); uint8_t rx;
tr.rx_buf = (unsigned long)&rx;
tr.len = sizeof(tx);
tr.speed_hz = RF24_SPIDEV_SPEED;
tr.delay_usecs = 0; tr.delay_usecs = 0;
tr.cs_change = 1; tr.bits_per_word = RF24_SPIDEV_BITS;
tr.speed_hz = this->speed; tr.cs_change = 0;
tr.bits_per_word = this->bits;*/
int ret;
ret = ioctl(this->fd, SPI_IOC_MESSAGE(1), &tr); ret = ioctl(this->fd, SPI_IOC_MESSAGE(1), &tr);
if (ret < 1) if (ret < 1)
{ {
pthread_mutex_unlock (&spiMutex);
perror("can't send spi message"); perror("can't send spi message");
abort(); abort();
} }
pthread_mutex_unlock (&spiMutex); return rx;
return rx[0];
} }
//void bcm2835_spi_transfernb(char* tbuf, char* rbuf, uint32_t len)
void SPI::transfernb(char* tbuf, char* rbuf, uint32_t len) void SPI::transfernb(char* tbuf, char* rbuf, uint32_t len)
{ {
struct spi_ioc_transfer tr;
pthread_mutex_lock (&spiMutex); memset(&tr, 0, sizeof(tr));
int ret; tr.tx_buf = (unsigned long)tbuf;
this->init(); tr.rx_buf = (unsigned long)rbuf;
struct spi_ioc_transfer tr = { tr.len = len;
tr.tx_buf = (unsigned long)tbuf, tr.speed_hz = RF24_SPIDEV_SPEED;
tr.rx_buf = (unsigned long)rbuf,
tr.len = len,//ARRAY_SIZE(tx),
tr.cs_change=1,
tr.delay_usecs = 0,
tr.bits_per_word = this->bits,
};
tr.speed_hz = this->speed,
//Note: On RPi, for some reason I started getting 'bad message' errors, and changing the struct as below fixed it, until an update...??
// One byte is transfered at once
//uint8_t tx[] = {0};
//tx[0] = tx_;
//uint8_t rx[ARRAY_SIZE(tx)] = {0};
/*struct spi_ioc_transfer tr;
tr.tx_buf = (unsigned long)tbuf;//(unsigned long)tx;
tr.rx_buf = (unsigned long)rbuf;//(unsigned long)rx;
tr.len = len;//ARRAY_SIZE(tx);
tr.delay_usecs = 0; tr.delay_usecs = 0;
tr.cs_change = 1; tr.bits_per_word = RF24_SPIDEV_BITS;
tr.speed_hz = this->speed; tr.cs_change = 0;
tr.bits_per_word = this->bits;*/
int ret;
ret = ioctl(this->fd, SPI_IOC_MESSAGE(1), &tr); ret = ioctl(this->fd, SPI_IOC_MESSAGE(1), &tr);
if (ret < 1) if (ret < 1)
{ {
pthread_mutex_unlock (&spiMutex);
perror("can't send spi message"); perror("can't send spi message");
abort(); abort();
} }
pthread_mutex_unlock (&spiMutex);
//return rx[0];
} }
void SPI::transfern(char* buf, uint32_t len)
{
transfernb(buf, buf, len);
}
SPI::~SPI() { SPI::~SPI() {
if (!(this->fd < 0)) if (!(this->fd < 0))
close(this->fd); close(this->fd);
} }
...@@ -23,27 +23,13 @@ ...@@ -23,27 +23,13 @@
* @{ * @{
*/ */
#include <string>
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <inttypes.h> #include <inttypes.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#ifndef RF24_SPIDEV_SPEED #ifndef RF24_SPIDEV_SPEED
/* 8MHz as default */ /* 8MHz as default */
#define RF24_SPIDEV_SPEED 8000000 #define RF24_SPIDEV_SPEED 8000000
#endif #endif
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
using namespace std;
class SPI { class SPI {
public: public:
...@@ -59,10 +45,10 @@ public: ...@@ -59,10 +45,10 @@ public:
/** /**
* Transfer a single byte * Transfer a single byte
* @param tx_ Byte to send * @param tx Byte to send
* @return Data returned via spi * @return Data returned via spi
*/ */
uint8_t transfer(uint8_t tx_); uint8_t transfer(uint8_t tx);
/** /**
* Transfer a buffer of data * Transfer a buffer of data
...@@ -77,20 +63,14 @@ public: ...@@ -77,20 +63,14 @@ public:
* @param buf Pointer to a buffer of data * @param buf Pointer to a buffer of data
* @param len Length of the data * @param len Length of the data
*/ */
void transfern(char* buf, uint32_t len); void transfern(char* buf, uint32_t len) {
transfernb(buf, buf, len);
}
virtual ~SPI(); ~SPI();
private: private:
/** Default SPI device */
string device;
/** SPI Mode set */
uint8_t mode;
/** word size*/
uint8_t bits;
/** Set SPI speed*/
uint32_t speed;
int fd; int fd;
void init(); void init();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment