linux用户层通过spi读写cpld

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 < 1)
        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("text 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;
}



  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CPLD是可编程逻辑器件(Complex Programmable Logic Device)的缩写,允许我们对其进行编程以实现特定的逻辑功能,而SPI是串行外设接口(Serial Peripheral Interface)的缩写,用于连接和交换数据的协议。 SPI Slave指的是SPI总线上的从设备,它被设计用来接收主设备(SPI Master)的指令和数据,并返回响应。CPLD可以被编程为充当SPI从设备,因此可以作为SPI系统中的一个功能模块使用。 在一个典型的SPI通信中,CPLD作为SPI Slave可以连接到SPI总线上的其他设备,例如传感器、存储器等。当主设备想要与CPLD通信时,它会发送一系列的时钟和数据信号,CPLD会接收并解析这些信号。根据主设备发送的指令和数据,CPLD可以执行相应的操作,并将结果返回给主设备。 CPLD可编程的优势使得我们可以根据需要自定义CPLDSPI Slave功能。我们可以编写逻辑代码,定义CPLD的数据传输和处理方式,以适应我们的具体应用需求。例如,我们可以编程CPLD实现SPI从设备上的各种功能,如数据存储、数据采集、数字信号处理等。 总的来说,CPLD作为SPI Slave,可以充当SPI系统中的一个从设备,接收主设备的指令和数据,并返回响应。通过编程CPLD的逻辑代码,我们可以自定义其功能,以实现特定的数据处理和应用需求。这种灵活性使得CPLD在许多嵌入式系统中得到广泛应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值