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 @@
#include "spi.h"
#include <pthread.h>
static pthread_mutex_t spiMutex;
#include <fcntl.h>
#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) {
}
void SPI::begin(int busNo){
this->device = "/dev/spidev0.0";
/* set spidev accordingly to busNo like:
* busNo = 23 -> /dev/spidev2.3
*
* a bit messy but simple
* */
this->device[11] += (busNo / 10) % 10;
this->device[13] += busNo % 10;
this->bits = 8;
this->speed = RF24_SPIDEV_SPEED;
this->mode=0;
//this->mode |= SPI_NO_CS;
this->init();
}
void SPI::init()
{
int ret;
char device[] = "/dev/spidev0.0";
device[11] += (busNo / 10) % 10;
device[13] += busNo % 10;
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)
{
......@@ -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
*/
ret = ioctl(this->fd, SPI_IOC_WR_MODE, &this->mode);
ret = ioctl(this->fd, SPI_IOC_WR_MODE, &mode);
if (ret == -1)
{
perror("can't set spi mode");
abort();
}
ret = ioctl(this->fd, SPI_IOC_RD_MODE, &this->mode);
ret = ioctl(this->fd, SPI_IOC_RD_MODE, &mode);
if (ret == -1)
{
perror("can't set spi mode");
......@@ -68,14 +75,14 @@ void SPI::init()
/*
* 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)
{
perror("can't set bits per word");
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)
{
perror("can't set bits per word");
......@@ -84,14 +91,14 @@ void SPI::init()
/*
* 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)
{
perror("can't set max speed hz");
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)
{
perror("can't set max speed hz");
......@@ -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;
tr.tx_buf = (unsigned long)tx;
tr.rx_buf = (unsigned long)rx;
tr.len = ARRAY_SIZE(tx);
memset(&tr, 0, sizeof(tr));
tr.tx_buf = (unsigned long)&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.cs_change = 1;
tr.speed_hz = this->speed;
tr.bits_per_word = this->bits;*/
tr.bits_per_word = RF24_SPIDEV_BITS;
tr.cs_change = 0;
int ret;
ret = ioctl(this->fd, SPI_IOC_MESSAGE(1), &tr);
if (ret < 1)
{
pthread_mutex_unlock (&spiMutex);
perror("can't send spi message");
abort();
}
pthread_mutex_unlock (&spiMutex);
return rx[0];
return rx;
}
//void bcm2835_spi_transfernb(char* tbuf, char* rbuf, uint32_t len)
void SPI::transfernb(char* tbuf, char* rbuf, uint32_t len)
{
pthread_mutex_lock (&spiMutex);
int ret;
this->init();
struct spi_ioc_transfer tr = {
tr.tx_buf = (unsigned long)tbuf,
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);
struct spi_ioc_transfer tr;
memset(&tr, 0, sizeof(tr));
tr.tx_buf = (unsigned long)tbuf;
tr.rx_buf = (unsigned long)rbuf;
tr.len = len;
tr.speed_hz = RF24_SPIDEV_SPEED;
tr.delay_usecs = 0;
tr.cs_change = 1;
tr.speed_hz = this->speed;
tr.bits_per_word = this->bits;*/
tr.bits_per_word = RF24_SPIDEV_BITS;
tr.cs_change = 0;
int ret;
ret = ioctl(this->fd, SPI_IOC_MESSAGE(1), &tr);
if (ret < 1)
{
pthread_mutex_unlock (&spiMutex);
perror("can't send spi message");
abort();
}
pthread_mutex_unlock (&spiMutex);
//return rx[0];
}
void SPI::transfern(char* buf, uint32_t len)
{
transfernb(buf, buf, len);
}
SPI::~SPI() {
if (!(this->fd < 0))
close(this->fd);
}
......@@ -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 <linux/types.h>
#include <linux/spi/spidev.h>
#ifndef RF24_SPIDEV_SPEED
/* 8MHz as default */
#define RF24_SPIDEV_SPEED 8000000
#endif
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
using namespace std;
class SPI {
public:
......@@ -59,10 +45,10 @@ public:
/**
* Transfer a single byte
* @param tx_ Byte to send
* @param tx Byte to send
* @return Data returned via spi
*/
uint8_t transfer(uint8_t tx_);
uint8_t transfer(uint8_t tx);
/**
* Transfer a buffer of data
......@@ -77,20 +63,14 @@ public:
* @param buf Pointer to a buffer of 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:
/** Default SPI device */
string device;
/** SPI Mode set */
uint8_t mode;
/** word size*/
uint8_t bits;
/** Set SPI speed*/
uint32_t speed;
int fd;
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