Project

General

Profile

spidevice.cpp

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

Download (3.01 KB)

 
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
}
Add picture from clipboard (Maximum size: 600 MB)