linux应用层读写idt8a34002

本文介绍了一种使用SPI接口对IDT8A34002芯片进行读写的方法。详细解释了SPI通信的格式要求,并提供了具体的C语言实现代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SPI读写idt8a34002

通过手册可知spi读写idt8a34002需要满足一定的格式。
比如:
写0x50到0xCBE4
读0xC024
SPI1-byte写0xCBE4 0x50
可以发现
写满足格式:
[7C] [LOW(8bit)&0x80] [HIGH(8bit)] [10] [20]
[LOW(8bit)&0x7F] 50
读满足格式:
[7C] [LOW(8bit)&0x80] [HIGH(8bit)] [10] [20]
[LOW(8bit)&0x7F] 00

整理得C代码

#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 = 300 * 1000 * 1000 / 2 / 64;
static uint16_t delay;

uint8_t default_rx[5] = {0};

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

/*************
 * 初始化idt8a34002
**************/
static int idt8a34002_init(void)
{
    int fd, ret = 0;
    char *device = "/dev/spidev1.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;
}

void idt8a34002_write(uint16_t page_reg, uint8_t value)
{
    int fd;
    fd = idt8a34002_init();

    uint8_t page1 = page_reg & 0x0080 ? 0x80 : 0x00;
    uint8_t page2 = page_reg >> 8;
    uint8_t reg   = page_reg & 0x7F;

    uint8_t default_tx_page[] = {0x7C, page1, page2, 0x10, 0x20};
    uint8_t default_tx_reg[]  = {reg, value};

    transfer(fd, default_tx_page, NULL, sizeof(default_tx_page));
    transfer(fd, default_tx_reg,  NULL, sizeof(default_tx_reg));

#if 0
    printf("default_rx: %2x %2x\n", default_rx[0], default_rx[1]);
#endif

    printf("IDT8a34002 write:page=0x%02x reg=0x%02x value=0x%02x\n", page2, page_reg & 0xFF, value);
    close(fd);
}

uint8_t idt8a34002_read(uint16_t page_reg)
{
    uint8_t value = 0;
    int fd;
    fd = idt8a34002_init();

    uint8_t page1 = page_reg & 0x0080 ? 0x80 : 0x00;
    uint8_t page2 = page_reg >> 8;
    uint8_t reg   = page_reg & 0xFF | 0x80;

    uint8_t default_tx_page[] = {0x7C, page1, page2, 0x10, 0x20};
    uint8_t default_tx_reg[]  = {reg , 0x00};

    transfer(fd, default_tx_page, NULL, sizeof(default_tx_page));
    transfer(fd, default_tx_reg, default_rx, sizeof(default_tx_reg));

#if 0
    printf("default_rx: %2x %2x\n", default_rx[0], default_rx[1]);
#endif

    value = default_rx[1];
    printf("IDT8a34002 read:page=0x%02x reg=0x%02x value=0x%02x\n", page2, page_reg & 0xFF, value);

    close(fd);

    return value;
}

/*************
 * main 
**************/
int main(int argc, char *argv[])
{
    uint16_t page_reg;
    uint8_t value;

    if (2 == argc) {
        page_reg = strtoul(argv[1], NULL, 16);
        value = idt8a34002_read(page_reg);
        return value;
    } else if (3 == argc) {
        page_reg = strtoul(argv[1], NULL, 16);
        value    = strtoul(argv[2], NULL, 16);

        idt8a34002_read(page_reg);
        idt8a34002_write(page_reg, value);
        idt8a34002_read(page_reg);
    }else {
        printf("./idt [reg] [value]\n");
    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值