LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Hardware > Linux - Embedded & Single-board computer
User Name
Password
Linux - Embedded & Single-board computer This forum is for the discussion of Linux on both embedded devices and single-board computers (such as the Raspberry Pi, BeagleBoard and PandaBoard). Discussions involving Arduino, plug computers and other micro-controller like devices are also welcome.

Notices


Reply
  Search this Thread
Old 04-01-2014, 08:05 AM   #1
Oromis_32
LQ Newbie
 
Registered: Nov 2013
Posts: 9

Rep: Reputation: Disabled
Asynchronous SPI


Hi,

I use SPI to get data from an Analog/Digital converter. I have a userspace C++ program that does the following:

Code:
struct spi_ioc_transfer tr;
tr.tx_buf = (unsigned long) tx;
tr.rx_buf = (unsigned long) rx;
tr.len = size;
tr.delay_usecs = 0;
tr.speed_hz = this->speed;
tr.bits_per_word = 8;
tr.cs_change = 0;

if(ioctl(this->file, SPI_IOC_MESSAGE(1), &tr) < 1)
// Error checking skipped
tx and rx are defined like this:
Code:
char tx[] = { 0x06, 0x80, 0x00 };
char rx[3];
The first 1,5 Bytes of tx contain the measurement request and the converter writes the result into the last 1,5 Bytes of rx. All works well.

Unfortunately, the whole thing is way too slow. It blocks for 6,6ms on my board, which is not what i want. Is there a possibility to speed the call up or at least do it asynchronously, so that the application can do something useful in the mean time (Apart from spawning an additional thread)?

Thanks for any ideas

David
 
Old 04-15-2014, 01:39 PM   #2
elucches
Member
 
Registered: Jan 2011
Posts: 108

Rep: Reputation: 11
Hi, check <linux kernel source directory>/Documentation/spi/spi_summary. I worked with SPI some years ago and it worked very well, but I don't remember the details right now.
 
Old 04-16-2014, 01:46 AM   #3
Oromis_32
LQ Newbie
 
Registered: Nov 2013
Posts: 9

Original Poster
Rep: Reputation: Disabled
Thanks for your reply.

The documentation you suggested describes how to build an SPI driver. Am I supposed to write my own driver? I have never done that before... Do you expect a large performance advantage over the userspace API?
 
Old 04-17-2014, 12:55 PM   #4
elucches
Member
 
Registered: Jan 2011
Posts: 108

Rep: Reputation: 11
I'm sorry, that document is just where I had found out CPOL and CPHA values, but I guess it's the only reference I wrote down back then.

Here are some fragments of the code I wrote years ago.

Initialization:
Code:
int             spidev_fd;
uint8_t         spi_tx_buf,
                spi_mode,
                spi_bpw;
uint8_t         spi_rx_buf = 0;
uint16_t        spi_delay_us = 0; // if nonzero, how long to delay after the last bit transfer before optionally deselecting
                                  // the device before the next transfer
uint32_t        spi_speed;

static const char * spi_device = "/dev/spidev0.0";

// open SPI device
spidev_fd = open(spi_device, O_RDWR);

// set SPI mode
spi_mode |= SPI_CPHA;
ret = ioctl(spidev_fd, SPI_IOC_WR_MODE, &spi_mode);
ret = ioctl(spidev_fd, SPI_IOC_RD_MODE, &spi_mode);

// set number of bits per word
spi_bpw = 8;
ret = ioctl(spidev_fd, SPI_IOC_WR_BITS_PER_WORD, &spi_bpw);
ret = ioctl(spidev_fd, SPI_IOC_RD_BITS_PER_WORD, &spi_bpw);

// set max speed (in Hz)
spi_speed = 500 * 1000;
ret = ioctl(spidev_fd, SPI_IOC_WR_MAX_SPEED_HZ, &spi_speed);
ret = ioctl(spidev_fd, SPI_IOC_RD_MAX_SPEED_HZ, &spi_speed);
Inside a function "spi_transfer" I put:
Code:
struct spi_ioc_transfer tr = {
         .tx_buf = (unsigned long) &spi_tx_buf,
         .rx_buf = (unsigned long) &spi_rx_buf,
         .len = sizeof(spi_tx_buf),
         .delay_usecs = spi_delay_us,
         .speed_hz = spi_speed,
         .bits_per_word = spi_bpw,
};

ret = ioctl(spidev_fd, SPI_IOC_MESSAGE(1), &tr);
And then I used, for example:
Code:
spi_tx_buf = 0; // send anything to get data from the ADC
spi_transfer();
fsr = spi_rx_buf; // FSR0 (Reset Value = 0x59)
I'm not coding for embedded boards anymore, but I'm willing to recall what I did if it helps you.

Regards,
Esteban
 
Old 04-22-2014, 09:06 AM   #5
Oromis_32
LQ Newbie
 
Registered: Nov 2013
Posts: 9

Original Poster
Rep: Reputation: Disabled
Hi, thanks for your reply!

Unfortunately, this is already the way I'm doing it and it's too slow. But thanks anyway for your help.
 
Old 06-25-2017, 12:29 PM   #6
SoajanII
LQ Newbie
 
Registered: Jun 2017
Posts: 1

Rep: Reputation: Disabled
I have almost exactly the same problem. But the unwanted delay varies between 6-30 ms. Were you able to come up with a solution?
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Asynchronous Serial I/O bear820301 Programming 5 11-12-2010 10:46 PM
Asynchronous IO shogun1234 Linux - Kernel 3 08-11-2010 02:26 PM
regarding asynchronous signal sky rulz Programming 1 04-22-2009 08:45 AM
Asynchronous Notification beparas Programming 3 03-09-2009 05:12 AM
Asynchronous file I/O BradDaBug Programming 5 03-19-2006 05:11 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Hardware > Linux - Embedded & Single-board computer

All times are GMT -5. The time now is 01:01 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration