spi_ioc_message
Hi,
I have a problem sending a SPI message with ROS using ioctl. In general, i can connect to the SPI port using ROS and I am able to send one byte at a time. The problem is, when I am trying to send more then one byte (length > 1) with the ROS node, I get a error from the ioctl. The exact same program (except the ROS part) running as a normal C-program works fine even by sending more then one bytes at a time. Has anyone any idea how to fix this issue in ROS?
Here is the code i use:
void SpiWriteRead(int length, const char *device, uint8_t *msg)
{
// Initialize parameters
uint8_t mode = 0;
uint8_t bits = 8;
uint32_t speed = 32000;
// Open device
int fd = open(device, O_RDWR);
if (fd < 0) {
ROS_ERROR("Can't open device");
exit(1);
}
// SPI mode
int ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
if (ret < 0) {
ROS_ERROR("Can't set spi mode");
exit(1);
}
// Bits per word
ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
if (ret < 0) {
ROS_ERROR("Can't set bits per word");
exit(1);
}
// Max speed, 1ms per 32bit command --> 32kHz
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
if (ret < 0) {
ROS_ERROR("Can't set max speed");
exit(1);
}
unsigned char tx[256];
unsigned char rx[256];
for (int i = 0; i < length; i++) {
tx[i] = 0x00;
rx[i] = 0x00;
}
struct spi_ioc_transfer tr[256];
for (int i = 0; i < length; i++) {
tr[i].tx_buf = (unsigned long)&tx[i];
tr[i].rx_buf = (unsigned long)&rx[i];
tr[i].len = 1;
tr[i].delay_usecs = 1000;
tr[i].speed_hz = speed;
tr[i].bits_per_word = 8;
}
ret = ioctl(fd, SPI_IOC_MESSAGE(length), tr);
if (ret < 1)
{
ROS_ERROR("Error read or write - ioctl");
exit(1);
}
// Close device
close(fd);
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "spiInterface");
ros::NodeHandle nh;
ros::Duration duration(1. / 24.);
// Length of byte stream
int length = 2;
sleep(2);
while (ros::ok())
{
unsigned char rightMsg[] = { 0x00, 0x77, 0x00, 0x77, 0x00, 0x77, 0x00 };
const char *dev0 = "/dev/spidev1.0";
SpiWriteRead(length, dev0, rightMsg);
duration.sleep();
}
return 0;
}