SPI读写idt8a34002
通过手册可知spi读写idt8a34002需要满足一定的格式。
比如:
写0x50到0xCBE4
读0xC024
可以发现
写满足格式:
[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;
}