Im looking for a simple example for raspberrypi using the spi communications via spi dev. google has not been kind to me show some results. Most SPI dev examples are python while i need it to be C/C++. I was hoping you could help me show me a code snippet / example as basic as a loopback test. I think that would be enough so i can build what i need down the road. it doesnt even need to have the functions for setting the GPIO as i already have codes for them. just the raw setting of clock speed and sendRecieveByte functions.
Thank you
Re: simple examples for C/C++ spi communications using spidev
this relies on a daemon running on the background right? would you have to happen to have a example for purely c/c++ just like your minimal examples? or i am misunderstanding how spidev works and inorder to use it inside c/c++ there must be a daemonjoan wrote: ↑Sun Feb 21, 2021 4:54 pmspi-driver-speed.c at http://abyz.me.uk/rpi/pigpio/faq.html#How_fast_is_SPI
Re: simple examples for C/C++ spi communications using spidev
No, it does not depend on pigpio. It uses spidev. I use that code to compare spidev's performance with the performance of the pigpio SPI driver.
Re: simple examples for C/C++ spi communications using spidev
ohh ! if you dont mind me asking why is the spidev so slow? although the spidev performance is within what i need, i am curious as it may become a problem in the future
Re: simple examples for C/C++ spi communications using spidev
I haven't bothered to find out precisely why as it's outside my control. I'd guess the layoff between userland and the kernel is soaking up the time. pigpio stays in userland for the transaction.
Re: simple examples for C/C++ spi communications using spidev
I noticed that when executing the example code (http://abyz.me.uk/rpi/pigpio/code/spi-driver-speed.c) i dont see the signals in my logic analyzer. Is this normal for the test file or something is wrong? I am probing SPI0 and the code is set to SPI0 the bus speed is also 1Mhz which is far from the 24mHz limit of y logic analyzer
Re: simple examples for C/C++ spi communications using spidev
The code assumes you have correctly configured the SPI bus, e.g. by enabling it with raspi-config or by adding the correct entries in /boot/config.txt. It also assumes you haven't changed the modes of any GPIO that were configured for SPI.
Re: simple examples for C/C++ spi communications using spidev
ahhh you are absolutely right i did a reboot and i can see it, only the serial clock though.
Also is it normal for the clock to fluctuate so much 4-12mHz (set to 10Mhz bps) and it would seem i cant puush it to 20Mhz
Re: simple examples for C/C++ spi communications using spidev
I would expect the clock to be stable, but it's not something I have ever tested.
- DougieLawson
- Posts: 40821
- Joined: Sun Jun 16, 2013 11:19 pm
- Location: A small cave in deepest darkest Basingstoke, UK
- Contact: Website Twitter
Re: simple examples for C/C++ spi communications using spidev
Code: Select all
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <fcntl.h>
#include <time.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>
#define MAX7219_REG_NOOP 0x00
#define MAX7219_REG_DIGIT0 0x01
#define MAX7219_REG_DIGIT1 0x02
#define MAX7219_REG_DIGIT2 0x03
#define MAX7219_REG_DIGIT3 0x04
#define MAX7219_REG_DIGIT4 0x05
#define MAX7219_REG_DIGIT5 0x06
#define MAX7219_REG_DIGIT6 0x07
#define MAX7219_REG_DIGIT7 0x08
#define MAX7219_REG_DECODEMODE 0x09
#define MAX7219_REG_INTENSITY 0x0A
#define MAX7219_REG_SCANLIMIT 0x0B
#define MAX7219_REG_SHUTDOWN 0x0C
#define MAX7219_REG_DISPLAYTEST 0x0F
#define CMD_WRITE 0x40
typedef struct
{
int digits[8];
} max7219;
max7219 header;
int spi_fd;
struct sigaction act;
static char *spiDevice = "/dev/spidev0.1";
static uint8_t spiBPW = 8;
static uint32_t spiSpeed = 5000000;
static uint16_t spiDelay = 0;
int spiOpen(char* dev)
{
if((spi_fd = open(dev, O_RDWR)) < 0)
{
printf("error opening %s\n",dev);
return -1;
}
return 0;
}
void writeByte(uint8_t reg, uint8_t data)
{
uint8_t spiBufTx [3];
uint8_t spiBufRx [3];
struct spi_ioc_transfer spi;
memset (&spi, 0, sizeof(spi));
spiBufTx [0] = CMD_WRITE;
spiBufTx [1] = reg;
spiBufTx [2] = data;
spi.tx_buf =(unsigned long)spiBufTx;
spi.rx_buf =(unsigned long)spiBufRx;
spi.len = 3;
spi.delay_usecs = spiDelay;
spi.speed_hz = spiSpeed;
spi.bits_per_word = spiBPW;
ioctl(spi_fd, SPI_IOC_MESSAGE(1), &spi);
}
void writeBytes(max7219 *header, int cmd, int data)
{
if(!header) return;
writeByte(cmd, data);
}
void setBrightness(max7219 *header, int bright)
{
if(!header) return;
if (bright < 0) bright = 0;
if (bright > 15) bright = 15;
writeBytes(header, MAX7219_REG_INTENSITY, bright);
}
void initialiseDisplay(max7219 *header)
{
spiOpen(spiDevice);
writeBytes(header, MAX7219_REG_SCANLIMIT, 7);
writeBytes(header, MAX7219_REG_DECODEMODE, 0xff);
writeBytes(header, MAX7219_REG_SHUTDOWN, 1);
writeBytes(header, MAX7219_REG_DISPLAYTEST, 0);
setBrightness(header, 5);
}
void byte_to_binary(int x)
{
static char b[9];
b[0] = '\0';
int z;
for (z = 128; z > 0; z >>= 1)
{
strcat(b, ((x & z) == z) ? "1" : "0");
}
printf("%s", b);
}
void digitDisplay(max7219 *header)
{
int i;
if(!header) return;
for (i=0; i<8; i++)
{
writeBytes(header, i+1, header->digits[i]);
}
}
void clearDisplay(max7219 *header)
{
int i;
if(!header) return;
for (i=0; i<8; i++) {
header->digits[i] = 0x0F;
}
digitDisplay(header);
}
uint8_t asciiToBCD (uint8_t chr)
{
uint8_t bcd_value;
bcd_value = (chr - 48);
return bcd_value;
}
void writeDigits(max7219 *header, char chars[12])
{
int i,j;
if (!header) return;
i = 7;
j = 0;
while (j <= 11 && i >= 0)
{
switch ((int)chars[j]) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
header->digits[i] = asciiToBCD(chars[j]);
j++;
i--;
break;
case ' ':
header->digits[i] = 0x0F;
j++;
i--;
break;
case '-':
header->digits[i] = 0x0a;
j++;
i--;
break;
case ':':
header->digits[i] = 0x8f;
j++;
i--;
break;
case '.':
header->digits[i+1] = header->digits[i+1] + 0x80;
j++;
break;
case 0x00:
j = 12;
i = -1;
break;
default:
j++;
break;
}
}
digitDisplay(header);
}
void sig_handler(int signum, siginfo_t *info, void *ptr)
{
clearDisplay(&header);
printf("Received signal %d\n", signum);
printf("Signal originated from process %lu\n",
(unsigned long)info->si_pid);
exit(0);
}
int main()
{
memset(&act, 0, sizeof(act));
act.sa_sigaction = sig_handler;
act.sa_flags = SA_SIGINFO;
sigaction(SIGTERM, &act, NULL);
char chars[12] = "12:34:56";
initialiseDisplay(&header);
clearDisplay(&header);
while (1)
{
clearDisplay(&header);
writeDigits(&header, chars);
sleep(1);
}
return 0;
}
Any language using left-hand whitespace for syntax is ridiculous
Any DMs sent on Twitter will be answered next month.
Fake doctors - are all on my foes list.
Any requirement to use a crystal ball or mind reading will result in me ignoring your question.
Any DMs sent on Twitter will be answered next month.
Fake doctors - are all on my foes list.
Any requirement to use a crystal ball or mind reading will result in me ignoring your question.
Re: simple examples for C/C++ spi communications using spidev
SPI_IOC_MESSAGE does allow you to send more than one transaction at a time, I wonder how this impacts overall performance.
Re: simple examples for C/C++ spi communications using spidev
Re: simple examples for C/C++ spi communications using spidev
Some results. Perhaps not as dramatic as I thought.
Code: Select all
3 byte transfers 1Mbps IOCS
pi4b:~ $ ./a.out 3 1000000 10000 1
sps=6543.9: 3 bytes @ 1000000 bps iocs 1(loops=10000 time=1.5)
pi4b:~ $ ./a.out 3 1000000 10000 2
sps=7662.8: 3 bytes @ 1000000 bps iocs 2(loops=10000 time=2.6)
pi4b:~ $ ./a.out 3 1000000 10000 3
sps=8031.5: 3 bytes @ 1000000 bps iocs 3(loops=10000 time=3.7)
pi4b:~ $ ./a.out 3 1000000 10000 4
sps=8464.4: 3 bytes @ 1000000 bps iocs 4(loops=10000 time=4.7)
pi4b:~ $ ./a.out 3 1000000 10000 5
sps=8682.2: 3 bytes @ 1000000 bps iocs 5(loops=10000 time=5.8)
pi4b:~ $ ./a.out 3 1000000 10000 6
sps=8779.8: 3 bytes @ 1000000 bps iocs 6(loops=10000 time=6.8)
pi4b:~ $ ./a.out 3 1000000 10000 7
sps=8876.3: 3 bytes @ 1000000 bps iocs 7(loops=10000 time=7.9)
pi4b:~ $ ./a.out 3 1000000 10000 8
sps=8893.4: 3 bytes @ 1000000 bps iocs 8(loops=10000 time=9.0)
pi4b:~ $ ./a.out 3 1000000 10000 9
sps=8985.3: 3 bytes @ 1000000 bps iocs 9(loops=10000 time=10.0)
3 byte transfers 2Mbps IOCS
pi4b:~ $ ./a.out 3 2000000 10000 1
sps=11121.2: 3 bytes @ 2000000 bps iocs 1(loops=10000 time=0.9)
pi4b:~ $ ./a.out 3 2000000 10000 2
sps=15100.3: 3 bytes @ 2000000 bps iocs 2(loops=10000 time=1.3)
pi4b:~ $ ./a.out 3 2000000 10000 3
sps=18182.5: 3 bytes @ 2000000 bps iocs 3(loops=10000 time=1.6)
pi4b:~ $ ./a.out 3 2000000 10000 4
sps=19189.2: 3 bytes @ 2000000 bps iocs 4(loops=10000 time=2.1)
pi4b:~ $ ./a.out 3 2000000 10000 5
sps=20738.8: 3 bytes @ 2000000 bps iocs 5(loops=10000 time=2.4)
pi4b:~ $ ./a.out 3 2000000 10000 6
sps=21337.6: 3 bytes @ 2000000 bps iocs 6(loops=10000 time=2.8)
pi4b:~ $ ./a.out 3 2000000 10000 7
sps=21841.1: 3 bytes @ 2000000 bps iocs 7(loops=10000 time=3.2)
pi4b:~ $ ./a.out 3 2000000 10000 8
sps=21755.8: 3 bytes @ 2000000 bps iocs 8(loops=10000 time=3.7)
3 byte transfers 4Mbps IOCS
pi4b:~ $ ./a.out 3 4000000 10000 1
sps=12641.4: 3 bytes @ 4000000 bps iocs 1(loops=10000 time=0.8)
pi4b:~ $ ./a.out 3 4000000 10000 2
sps=20255.9: 3 bytes @ 4000000 bps iocs 2(loops=10000 time=1.0)
pi4b:~ $ ./a.out 3 4000000 10000 3
sps=26284.1: 3 bytes @ 4000000 bps iocs 3(loops=10000 time=1.1)
pi4b:~ $ ./a.out 3 4000000 10000 4
sps=29089.3: 3 bytes @ 4000000 bps iocs 4(loops=10000 time=1.4)
pi4b:~ $ ./a.out 3 4000000 10000 5
sps=31196.7: 3 bytes @ 4000000 bps iocs 5(loops=10000 time=1.6)
pi4b:~ $ ./a.out 3 4000000 10000 6
sps=32592.1: 3 bytes @ 4000000 bps iocs 6(loops=10000 time=1.8)
pi4b:~ $ ./a.out 3 4000000 10000 7
sps=32463.5: 3 bytes @ 4000000 bps iocs 7(loops=10000 time=2.2)
pi4b:~ $