@ShaneCCC
write program for master:
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/ioctl.h>
#include <sys/stat.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#define DEFAULT_SIZE 8192
static void pabort(const char *s)
{
perror(s);
abort();
}
static const char *device = "/dev/spidev0.0";
static uint32_t mode=SPI_MODE_0;
static uint8_t bits = 8;
static uint32_t speed = 5000000;
static int tx_len = 884;
static uint32_t count=1;
uint8_t default_tx[DEFAULT_SIZE] = {0};
static void hex_dump(const void *src, size_t length, char *prefix)
{
const unsigned char *address = src;
size_t ll=length;
printf("%s(0x%x) | ", prefix, count);
while (length-- > 0) {
if((ll-length)>6 && *address == 0)
*address++;
else
printf("%02X ", *address++);
}
printf("\n");
}
static void transfer(int fd)
{
int ret;
struct spi_ioc_transfer tr = {
.rx_buf = 0,
.tx_buf = (unsigned long)default_tx,
.len = tx_len,
.speed_hz = speed,
.bits_per_word = bits,
};
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
if (ret < 1)
pabort("can't send spi message");
hex_dump(default_tx, tx_len, "TX");
}
int main(int argc, char *argv[])
{
int ret = 0;
int fd;
fd = open(device, O_RDWR);
if (fd < 0)
pabort("can't open device");
/*
* spi mode
*/
ret = ioctl(fd, SPI_IOC_WR_MODE32, &mode);
if (ret == -1)
pabort("can't get spi mode");
ret = ioctl(fd, SPI_IOC_RD_MODE32, &mode);
if (ret == -1)
pabort("can't get spi mode");
/*
* bits per word
*/
ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
if (ret == -1)
pabort("can't set bits per word");
ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
if (ret == -1)
pabort("can't get bits per word");
/*
* max speed hz
*/
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
if (ret == -1)
pabort("can't set max speed hz");
ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
if (ret == -1)
pabort("can't get max speed hz");
printf("spi mode: 0x%x\n", mode);
printf("bits per word: %d\n", bits);
printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);
while(1){
memset(default_tx, 0, DEFAULT_SIZE);
default_tx[0] = 0xeb;
default_tx[1] = 0x90;
default_tx[2] = (count>>24)&0xff;
default_tx[3] = (count>>16)&0xff;
default_tx[4] = (count>>8)&0xff;
default_tx[5] = count&0xff;
default_tx[tx_len-2] = 0xaa;
default_tx[tx_len-1] = 0xaa;
transfer(fd);
count++;
usleep(5000);
}
close(fd);
return ret;
}
read program for slave:
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/ioctl.h>
#include <sys/stat.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#define DEFAULT_SIZE 8192
static void pabort(const char *s)
{
perror(s);
abort();
}
static const char *device = "/dev/spidev0.0";
static uint32_t mode=SPI_MODE_0;
static uint8_t bits = 8;
static uint32_t speed = 5000000;
static int rx_len = 884;
static uint32_t pre_count=0;
static uint32_t cur_count=0;
uint8_t default_rx[DEFAULT_SIZE] = {0, };
static uint32_t pre = 0;
static uint32_t cur = 0;
static void hex_dump(const void *src, size_t length, char *prefix)
{
const unsigned char *address = src;
if(cur==0){
cur=address[2]<<24| address[3]<<16| address[4]<<8| address[5];
pre=cur;
}else{
cur=address[2]<<24| address[3]<<16| address[4]<<8| address[5];
if(cur-pre!=1){
fprintf(stderr, "pre:%d, cur:%d------", pre, cur);
fprintf(stderr, "%s | %02X %02X %02X %02X %02X %02X %02X %02X\n\n",
prefix, address[0], address[1], address[2], address[3], address[4], address[5],
address[rx_len-2], address[rx_len-1]);
}
pre=cur;
}
}
static void transfer(int fd)
{
int ret;
struct spi_ioc_transfer tr = {
.rx_buf = (unsigned long)default_rx,
.tx_buf = 0,
.len = rx_len,
.speed_hz = speed,
.bits_per_word = bits,
};
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
if (ret < 1){
pabort("can't send spi message");
return;
}
hex_dump(default_rx, rx_len, "RX");
memset(default_rx, 0, DEFAULT_SIZE);
}
int main(int argc, char *argv[])
{
int ret = 0;
int fd;
fd = open(device, O_RDWR);
if (fd < 0)
pabort("can't open device");
/*
* spi mode
*/
ret = ioctl(fd, SPI_IOC_RD_MODE32, &mode);
if (ret == -1)
pabort("can't get spi mode");
/*
* bits per word
*/
ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
if (ret == -1)
pabort("can't set bits per word");
ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
if (ret == -1)
pabort("can't get bits per word");
/*
* max speed hz
*/
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
if (ret == -1)
pabort("can't set max speed hz");
ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
if (ret == -1)
pabort("can't get max speed hz");
fprintf(stderr, "spi mode: 0x%x\n", mode);
fprintf(stderr, "bits per word: %d\n", bits);
fprintf(stderr, "max speed: %d Hz (%d KHz)\n", speed, speed/1000);
while(1){
transfer(fd);
}
close(fd);
return ret;
}
slave device-tree config:
spi@3210000 {
status = "okay";
compatible = "nvidia,tegra186-spi-slave";
spi@0 {
compatible = "spidev";
reg = <0>;
spi-max-frequency = <65000000>;
};
};