1
|
/**
|
2
|
* \file spidevice.cpp
|
3
|
*
|
4
|
* \brief Wrapper class to communicate to device via spidev
|
5
|
*
|
6
|
* Websites:
|
7
|
* Critical Link - http://www.criticallink.com
|
8
|
*
|
9
|
* \copyright Critical Link LLC 2015
|
10
|
*/
|
11
|
|
12
|
#include <cstdio>
|
13
|
#include <cstring>
|
14
|
|
15
|
#include "spidevice.h"
|
16
|
|
17
|
tcSPIDevice::tcSPIDevice(std::string asDevice)
|
18
|
:msDevice(asDevice), mnFileDescriptor(-1)
|
19
|
{
|
20
|
openDevice();
|
21
|
}
|
22
|
|
23
|
tcSPIDevice::tcSPIDevice(const char* asDevice)
|
24
|
:msDevice(asDevice), mnFileDescriptor(-1)
|
25
|
{
|
26
|
openDevice();
|
27
|
}
|
28
|
|
29
|
tcSPIDevice::~tcSPIDevice()
|
30
|
{
|
31
|
closeDevice();
|
32
|
}
|
33
|
|
34
|
void tcSPIDevice::openDevice()
|
35
|
{
|
36
|
if(!this->isOpen()) {
|
37
|
mnFileDescriptor = open(msDevice.c_str(), O_RDWR);
|
38
|
|
39
|
if (mnFileDescriptor < 0) {
|
40
|
perror("SPIDevice constructor");
|
41
|
}
|
42
|
}
|
43
|
}
|
44
|
|
45
|
void tcSPIDevice::closeDevice()
|
46
|
{
|
47
|
if (mnFileDescriptor >= 0) {
|
48
|
close(mnFileDescriptor);
|
49
|
mnFileDescriptor = -1;
|
50
|
}
|
51
|
}
|
52
|
|
53
|
bool tcSPIDevice::isOpen()
|
54
|
{
|
55
|
return !(mnFileDescriptor < 0);
|
56
|
}
|
57
|
|
58
|
tsSPIConfiguration tcSPIDevice::getConfiguration()
|
59
|
{
|
60
|
tsSPIConfiguration rv;
|
61
|
|
62
|
rv.mnMode = -1;
|
63
|
rv.mnBits = -1;
|
64
|
rv.mnLsbType = -1;
|
65
|
rv.mnSpeed = -1;
|
66
|
|
67
|
if (ioctl(mnFileDescriptor, SPI_IOC_RD_MODE, &(rv.mnMode)) < 0) {
|
68
|
perror("SPI rd_mode");
|
69
|
}
|
70
|
|
71
|
if (ioctl(mnFileDescriptor, SPI_IOC_RD_LSB_FIRST, &(rv.mnLsbType))
|
72
|
< 0) {
|
73
|
perror("SPI rd_lsb_fist");
|
74
|
}
|
75
|
|
76
|
if (ioctl(mnFileDescriptor, SPI_IOC_RD_BITS_PER_WORD, &(rv.mnBits))
|
77
|
< 0) {
|
78
|
perror("SPI rd_bits_per_word");
|
79
|
}
|
80
|
|
81
|
if (ioctl(mnFileDescriptor, SPI_IOC_RD_MAX_SPEED_HZ, &(rv.mnSpeed))
|
82
|
< 0) {
|
83
|
perror("SPI rd_max_speed_hz");
|
84
|
}
|
85
|
|
86
|
return rv;
|
87
|
}
|
88
|
|
89
|
bool tcSPIDevice::setConfiguration(struct tsSPIConfiguration &arConfiguration)
|
90
|
{
|
91
|
bool rv = true;
|
92
|
|
93
|
if (ioctl(mnFileDescriptor, SPI_IOC_WR_MODE, &(arConfiguration.mnMode))
|
94
|
< 0) {
|
95
|
perror("SPI wr_mode");
|
96
|
rv = false;
|
97
|
}
|
98
|
|
99
|
if (ioctl(mnFileDescriptor, SPI_IOC_WR_LSB_FIRST,
|
100
|
&(arConfiguration.mnLsbType)) < 0) {
|
101
|
perror("SPI wr_lsb_fist");
|
102
|
rv = false;
|
103
|
}
|
104
|
|
105
|
if (ioctl(mnFileDescriptor, SPI_IOC_WR_BITS_PER_WORD,
|
106
|
&(arConfiguration.mnBits)) < 0) {
|
107
|
perror("SPI wr_bits_per_word");
|
108
|
rv = false;
|
109
|
}
|
110
|
|
111
|
if (ioctl(mnFileDescriptor, SPI_IOC_WR_MAX_SPEED_HZ,
|
112
|
&(arConfiguration.mnSpeed)) < 0) {
|
113
|
perror("SPI wr_max_speed_hz");
|
114
|
rv = false;
|
115
|
}
|
116
|
|
117
|
return rv;
|
118
|
}
|
119
|
|
120
|
void tcSPIDevice::write(char *apTxData, long anLen)
|
121
|
{
|
122
|
::write(mnFileDescriptor, apTxData, anLen);
|
123
|
}
|
124
|
|
125
|
void tcSPIDevice::read(char *apRxData, long anLen)
|
126
|
{
|
127
|
::read(mnFileDescriptor, apRxData, anLen);
|
128
|
}
|
129
|
|
130
|
void tcSPIDevice::duplex(char *apTxData, char *apRxData, long anLen)
|
131
|
{
|
132
|
struct spi_ioc_transfer xfer;
|
133
|
int status;
|
134
|
|
135
|
/* clear out the transfer struct */
|
136
|
memset(&xfer, 0, sizeof(xfer));
|
137
|
|
138
|
/* set the data to transfer; this is a pointer */
|
139
|
xfer.tx_buf = (unsigned long) apTxData;
|
140
|
/* set the length of the data to transfer in bytes */
|
141
|
xfer.len = anLen;
|
142
|
|
143
|
/* set the buffer for the data to receive; this can be NULL */
|
144
|
xfer.rx_buf = (unsigned long) apRxData;
|
145
|
/* length is in bytes */
|
146
|
xfer.len = anLen;
|
147
|
|
148
|
/* perform the operation, SPI_IOC_MESSAGE is 1 because there is only 1 frame message occurring */
|
149
|
status = ioctl(mnFileDescriptor, SPI_IOC_MESSAGE(1), &xfer);
|
150
|
if (status < 0) {
|
151
|
perror("SPI_IOC_MESSAGE");
|
152
|
}
|
153
|
}
|