cpld的通讯格式会有不同
我这使用的是32bit 需反转的
写时序:
读时序:
#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/types.h>
#include <linux/spi/spidev.h>
static void pabort(const char *s)
{
perror(s);
abort();
}
static uint32_t mode ;
static uint8_t bits = 8;
static uint32_t speed = 100000;
static uint16_t delay;
uint8_t default_rx[5] = {0};
unsigned char bit_reverse8(unsigned char c)
{
return ((c >> 7) & 0x1)|( (c << 7) & 0x80) \
| ((c >> 5) & 0x2)|( (c << 5) & 0x40) \
| ((c >> 3) & 0x4)|( (c << 3) & 0x20) \
| ((c >> 1) & 0x8)|( (c << 1) & 0x10) ;
}
static void transfer(int fd, uint8_t const *tx, uint8_t const *rx, size_t len)
{
int ret;
struct spi_ioc_transfer tr = {
.tx_buf = (unsigned long)tx,
.rx_buf = (unsigned long)rx,
.len = len,
.delay_usecs = delay,
.speed_hz = speed,
.bits_per_word = bits,
};
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
if (ret < 0)
printf("can't send spi message\n");
}
/*************
* cpld 读写接口
**************/
static int cpld_init(void)
{
int fd, ret = 0;
char *device = "/dev/spidev0.2";
fd = open(device, O_RDWR);
if (fd < 0)
pabort("can't open device");
ret = ioctl(fd, SPI_IOC_WR_MODE32, &mode);
if (ret == -1)
pabort("can't set spi mode");
ret = ioctl(fd, SPI_IOC_RD_MODE32, &mode);
if (ret == -1)
pabort("can't get spi mode");
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");
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");
#if 0
printf("open:%s\n", device);
printf("cpld:spi mode: 0x%x\n", mode);
printf("cpld:bits per word: %d\n", bits);
printf("cpld:max speed: %d Hz (%d KHz)\n", speed, speed/1000);
#endif
return fd;
}
uint8_t cpld_write(uint8_t reg, uint8_t data_out)
{
int fd;
fd = cpld_init();
uint8_t default_tx[] = {bit_reverse8(0x51), bit_reverse8(reg), 0, bit_reverse8(data_out)};
transfer(fd, default_tx, default_rx, sizeof(default_tx));
printf("cpld write: reg=0x%x data_out=0x%x\n", reg, data_out);
close(fd);
return 0;
}
uint8_t cpld_read(uint8_t reg)
{
uint8_t data_in[2] = {0};
int fd;
fd = cpld_init();
uint8_t default_tx[] = {bit_reverse8(0x50), bit_reverse8(reg&0xff), 0, 0};
transfer(fd, default_tx, default_rx, sizeof(default_tx));
#if 0
printf("default_tx: 0x%x 0x%x 0x%x 0x%x\n", default_tx[0], default_tx[1], default_tx[2], default_tx[3]);
printf("default_rx: %4x %4x %4x %4x\n", default_rx[0], default_rx[1], default_rx[2], default_rx[3]);
#endif
data_in[0] = bit_reverse8(default_rx[3]);
data_in[1] = bit_reverse8(default_rx[2]);
printf("cpld read: reg=0x%x data_in=0x%x\n", reg, data_in[0]);
close(fd);
return data_in[0];
}
/*************
* main
**************/
int main(int argc, char *argv[])
{
uint8_t reg, cpld_data_in, data_out = 0x00;
printf("test by fish.\n");
if(2 == argc){
reg = strtoul(argv[1], NULL, 16);
cpld_data_in = cpld_read(reg);
}else if(3 == argc){
reg = strtoul(argv[1], NULL, 16);
data_out = strtoul(argv[2], NULL, 16);
cpld_data_in = cpld_read(reg);
cpld_write(reg, data_out);
cpld_data_in = cpld_read(reg);
}else{
printf("./spi_cpld [reg] [data_out]\n");
}
return 0;
}