生活随笔
收集整理的這篇文章主要介紹了
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");
}
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 0printf("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);
#endifreturn 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 0printf("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]);
#endifdata_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];
}
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;
}
總結
以上是生活随笔為你收集整理的linux用户层通过spi读写cpld的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。