Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
R
RF24
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
xpstem
RF24
Commits
e234ba71
Commit
e234ba71
authored
Jan 04, 2017
by
plasticassius
Committed by
GitHub
Jan 04, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix SPIDEV interface (#315)
* fix SPIDEV interface * cleanup SPIDEV
parent
ab738fdf
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
83 additions
and
146 deletions
+83
-146
utility/SPIDEV/spi.cpp
utility/SPIDEV/spi.cpp
+65
-108
utility/SPIDEV/spi.h
utility/SPIDEV/spi.h
+18
-38
No files found.
utility/SPIDEV/spi.cpp
View file @
e234ba71
/*
/*
* File: spi.cpp
* File: spi.cpp
* Author: Purinda Gunasekara <purinda@gmail.com>
* Author: Purinda Gunasekara <purinda@gmail.com>
*
*
* Created on 24 June 2012, 11:00 AM
* Created on 24 June 2012, 11:00 AM
*
*
* Inspired from spidev test in linux kernel documentation
* Inspired from spidev test in linux kernel documentation
* www.kernel.org/doc/Documentation/spi/spidev_test.c
* www.kernel.org/doc/Documentation/spi/spidev_test.c
*/
*/
#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,153 +45,113 @@ void SPI::init()
...
@@ -48,153 +45,113 @@ 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"
);
abort
();
abort
();
}
}
/*
/*
* 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"
);
abort
();
abort
();
}
}
/*
/*
* 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"
);
abort
();
abort
();
}
}
}
}
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
.
delay_usecs
=
0
;
tr
.
len
=
len
,
//ARRAY_SIZE(tx),
tr
.
bits_per_word
=
RF24_SPIDEV_BITS
;
tr
.
cs_change
=
1
,
tr
.
cs_change
=
0
;
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.cs_change = 1;
tr.speed_hz = this->speed;
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
);
}
}
utility/SPIDEV/spi.h
View file @
e234ba71
/*
/*
* File: spi.h
* File: spi.h
* Author: Purinda Gunasekara <purinda@gmail.com>
* Author: Purinda Gunasekara <purinda@gmail.com>
*
*
* Created on 24 June 2012, 11:00 AM
* Created on 24 June 2012, 11:00 AM
*/
*/
...
@@ -13,7 +13,7 @@
...
@@ -13,7 +13,7 @@
* \cond HIDDEN_SYMBOLS
* \cond HIDDEN_SYMBOLS
* Class declaration for SPI helper files
* Class declaration for SPI helper files
*/
*/
/**
/**
* Example GPIO.h file
* Example GPIO.h file
*
*
...
@@ -22,48 +22,34 @@
...
@@ -22,48 +22,34 @@
* See RF24_arch_config.h for additional information
* See RF24_arch_config.h for additional information
* @{
* @{
*/
*/
#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:
/**
/**
* SPI constructor
* SPI constructor
*/
*/
SPI
();
SPI
();
/**
/**
* Start SPI
* Start SPI
*/
*/
void
begin
(
int
busNo
);
void
begin
(
int
busNo
);
/**
/**
* 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
* @param tbuf Transmit buffer
* @param tbuf Transmit buffer
...
@@ -76,24 +62,18 @@ public:
...
@@ -76,24 +62,18 @@ public:
* Transfer a buffer of data without an rx buffer
* Transfer a buffer of data without an rx buffer
* @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
();
};
};
/**
/**
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment