Project

General

Profile

RE: We want to know about SPI for CAN Interface with Linux » spidevice.cpp

Jonathan Cormier, 02/28/2019 04:44 PM

 
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
}
(1-1/2) Go to top
Add picture from clipboard (Maximum size: 1 GB)