生活随笔
收集整理的這篇文章主要介紹了
                                
linux用户层通过spi读写cpld
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.                        
 
                                
                            
                            
                            cpld的通訊格式會有不同
 我這使用的是32bit 需反轉(zhuǎn)的
 寫時序:
 
 讀時序:
 
 
#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;
}
                            總結(jié)
                            
                                以上是生活随笔為你收集整理的linux用户层通过spi读写cpld的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                            
                                如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。