Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1624054

Browse files
authored
device drivers lib add linux spi support
1 parent ed8c601 commit 1624054

File tree

8 files changed

+348
-16
lines changed

8 files changed

+348
-16
lines changed

boards/px4/sitl/default.cmake

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ px4_add_board(
88

99
DRIVERS
1010
#barometer # all available barometer drivers
11-
batt_smbus
11+
#batt_smbus
1212
camera_trigger
13-
differential_pressure # all available differential pressure drivers
14-
distance_sensor # all available distance sensor drivers
13+
#differential_pressure # all available differential pressure drivers
14+
#distance_sensor # all available distance sensor drivers
1515
gps
1616
#imu # all available imu drivers
1717
#magnetometer # all available magnetometer drivers

boards/px4/sitl/rtps.cmake

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ px4_add_board(
88

99
DRIVERS
1010
#barometer # all available barometer drivers
11-
batt_smbus
11+
#batt_smbus
1212
camera_trigger
13-
differential_pressure # all available differential pressure drivers
14-
distance_sensor # all available distance sensor drivers
13+
#differential_pressure # all available differential pressure drivers
14+
#distance_sensor # all available distance sensor drivers
1515
gps
1616
#imu # all available imu drivers
1717
#magnetometer # all available magnetometer drivers

boards/px4/sitl/test.cmake

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ px4_add_board(
88

99
DRIVERS
1010
#barometer # all available barometer drivers
11-
batt_smbus
11+
#batt_smbus
1212
camera_trigger
13-
differential_pressure # all available differential pressure drivers
14-
distance_sensor # all available distance sensor drivers
13+
#differential_pressure # all available differential pressure drivers
14+
#distance_sensor # all available distance sensor drivers
1515
gps
1616
#imu # all available imu drivers
1717
#magnetometer # all available magnetometer drivers

platforms/posix/cmake/sitl_tests.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ set(tests
3232
rc
3333
search_min
3434
servo
35-
sf0x
35+
#sf0x
3636
sleep
3737
uorb
3838
versioning

src/lib/drivers/device/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,11 @@ if (${PX4_PLATFORM} STREQUAL "nuttx")
4040
if ("${CONFIG_SPI}" STREQUAL "y")
4141
list(APPEND SRCS_PLATFORM nuttx/SPI.cpp)
4242
endif()
43-
else()
43+
elseif(UNIX AND NOT APPLE AND NOT (${PX4_PLATFORM} MATCHES "qurt")) #TODO: add linux PX4 platform type
44+
# Linux I2Cdev and SPIdev
4445
list(APPEND SRCS_PLATFORM
4546
posix/I2C.cpp
47+
posix/SPI.cpp
4648
)
4749
endif()
4850

src/lib/drivers/device/posix/SPI.cpp

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
/****************************************************************************
2+
*
3+
* Copyright (C) 2019 PX4 Development Team. All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions
7+
* are met:
8+
*
9+
* 1. Redistributions of source code must retain the above copyright
10+
* notice, this list of conditions and the following disclaimer.
11+
* 2. Redistributions in binary form must reproduce the above copyright
12+
* notice, this list of conditions and the following disclaimer in
13+
* the documentation and/or other materials provided with the
14+
* distribution.
15+
* 3. Neither the name PX4 nor the names of its contributors may be
16+
* used to endorse or promote products derived from this software
17+
* without specific prior written permission.
18+
*
19+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22+
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23+
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25+
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26+
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27+
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29+
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30+
* POSSIBILITY OF SUCH DAMAGE.
31+
*
32+
****************************************************************************/
33+
34+
/**
35+
* @file SPI.cpp
36+
*
37+
* Base class for devices connected via SPI.
38+
*
39+
*/
40+
41+
#include "SPI.hpp"
42+
43+
#ifdef __PX4_LINUX
44+
45+
#include <fcntl.h>
46+
#include <unistd.h>
47+
#include <sys/ioctl.h>
48+
#include <linux/types.h>
49+
#include <linux/spi/spidev.h>
50+
51+
#include <px4_config.h>
52+
53+
namespace device
54+
{
55+
56+
SPI::SPI(const char *name, const char *devname, int bus, uint32_t device, enum spi_mode_e mode, uint32_t frequency) :
57+
CDev(name, devname),
58+
_device(device),
59+
_mode(mode),
60+
_frequency(frequency)
61+
{
62+
DEVICE_DEBUG("SPI::SPI name = %s devname = %s", name, devname);
63+
64+
// fill in _device_id fields for a SPI device
65+
_device_id.devid_s.bus_type = DeviceBusType_SPI;
66+
_device_id.devid_s.bus = bus;
67+
_device_id.devid_s.address = (uint8_t)device;
68+
// devtype needs to be filled in by the driver
69+
_device_id.devid_s.devtype = 0;
70+
}
71+
72+
SPI::~SPI()
73+
{
74+
if (_fd >= 0) {
75+
::close(_fd);
76+
_fd = -1;
77+
}
78+
}
79+
80+
int
81+
SPI::init()
82+
{
83+
int ret = OK;
84+
85+
// Open the actual SPI device
86+
char dev_path[16];
87+
snprintf(dev_path, sizeof(dev_path), "/dev/spidev%i.%i", get_device_bus(), PX4_SPI_DEV_ID(_device));
88+
DEVICE_DEBUG("%s", dev_path);
89+
_fd = ::open(dev_path, O_RDWR);
90+
91+
if (_fd < 0) {
92+
PX4_ERR("could not open %s", dev_path);
93+
return PX4_ERROR;
94+
}
95+
96+
/* call the probe function to check whether the device is present */
97+
ret = probe();
98+
99+
if (ret != OK) {
100+
DEVICE_DEBUG("probe failed");
101+
return ret;
102+
}
103+
104+
/* do base class init, which will create the device node, etc. */
105+
ret = CDev::init();
106+
107+
if (ret != OK) {
108+
DEVICE_DEBUG("cdev init failed");
109+
return ret;
110+
}
111+
112+
/* tell the workd where we are */
113+
DEVICE_LOG("on SPI bus %d at %d (%u KHz)", get_device_bus(), PX4_SPI_DEV_ID(_device), _frequency / 1000);
114+
115+
return PX4_OK;
116+
}
117+
118+
int
119+
SPI::transfer(uint8_t *send, uint8_t *recv, unsigned len)
120+
{
121+
if ((send == nullptr) && (recv == nullptr)) {
122+
return -EINVAL;
123+
}
124+
125+
// set write mode of SPI
126+
int result = ::ioctl(_fd, SPI_IOC_WR_MODE, &_mode);
127+
128+
if (result == -1) {
129+
PX4_ERR("can’t set spi mode");
130+
return PX4_ERROR;
131+
}
132+
133+
spi_ioc_transfer spi_transfer[1] {}; // datastructures for linux spi interface
134+
135+
spi_transfer[0].tx_buf = (uint64_t)send;
136+
spi_transfer[0].rx_buf = (uint64_t)recv;
137+
spi_transfer[0].len = len;
138+
spi_transfer[0].speed_hz = _frequency;
139+
spi_transfer[0].bits_per_word = 8;
140+
//spi_transfer[0].delay_usecs = 10;
141+
spi_transfer[0].cs_change = true;
142+
143+
result = ::ioctl(_fd, SPI_IOC_MESSAGE(1), &spi_transfer);
144+
145+
if (result != (int)len) {
146+
PX4_ERR("write failed. Reported %d bytes written (%s)", result, strerror(errno));
147+
return -1;
148+
}
149+
150+
return 0;
151+
}
152+
153+
int
154+
SPI::transferhword(uint16_t *send, uint16_t *recv, unsigned len)
155+
{
156+
if ((send == nullptr) && (recv == nullptr)) {
157+
return -EINVAL;
158+
}
159+
160+
// set write mode of SPI
161+
int result = ::ioctl(_fd, SPI_IOC_WR_MODE, &_mode);
162+
163+
if (result == -1) {
164+
PX4_ERR("can’t set spi mode");
165+
return PX4_ERROR;
166+
}
167+
168+
int bits = 16;
169+
result = ::ioctl(_fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
170+
171+
if (result == -1) {
172+
PX4_ERR("can’t set 16 bit spi mode");
173+
return PX4_ERROR;
174+
}
175+
176+
spi_ioc_transfer spi_transfer[1] {}; // datastructures for linux spi interface
177+
178+
spi_transfer[0].tx_buf = (uint64_t)send;
179+
spi_transfer[0].rx_buf = (uint64_t)recv;
180+
spi_transfer[0].len = len * 2;
181+
spi_transfer[0].speed_hz = _frequency;
182+
//spi_transfer[0].bits_per_word = 8;
183+
//spi_transfer[0].delay_usecs = 10;
184+
spi_transfer[0].cs_change = true;
185+
186+
result = ::ioctl(_fd, SPI_IOC_MESSAGE(1), &spi_transfer);
187+
188+
if (result != (int)(len * 2)) {
189+
PX4_ERR("write failed. Reported %d bytes written (%s)", result, strerror(errno));
190+
return -1;
191+
}
192+
193+
return 0;
194+
}
195+
196+
} // namespace device
197+
198+
#endif // __PX4_LINUX

0 commit comments

Comments
 (0)