Linux环境:Ubuntu10.04
SDK版本:(Hi3518E_SDK_V1.0.3.0.tgz)Hi3518EV200R001C01SPC030
一、默认SPI相关模块已经全部编入了内核,所以不需要加载内核,查看dev/spi*即可发现,如下:
~ # ls /dev/spi*
/dev/spidev0.0 /dev/spidev1.0 /dev/spidev1.1
其中spidev0.0是SPI0片选0;spidev1.0是SPI1片选0;spidev1.1是SPI1片选1。
本次,我使用的是SPI1片选0,也就是spidev1.0,对应pin脚为SPI1_CSN0、SPI1_SCLK、SPI1_SDI、SPI_SDO;使用spidev1.0需要对上述引脚进行管脚复用配置,如下:
himm 0x200f0050 0x1 # muxctrl_reg20 0x1 复用为SPI1_SCLK
himm 0x200f0054 0x1 # muxctrl_reg21 0x1 复用为SPI1_SDO
himm 0x200f0058 0x1 # muxctrl_reg22 0x1 复用为SPI1_SDI
himm 0x200f005c 0x1 # muxctrl_reg23 0x1 复用为SPI1_CSN0
二、SPI1片选0初始化如下:
static int fd_a7196;
static int spi_a7196_init(void)
{
int ret = 0;
//打开SPI1片选0总线对应的设备文件,获取文件句柄
fd_a7196 = open(SPI_DEVICE, O_RDWR);
if (fd_a7196 < 0) {
printf("can't open %s \n", SPI_DEVICE);
return -1;
}
//通过ioctl设置SPI传输模式
ret = ioctl(fd_a7196, SPI_IOC_WR_MODE, &mode); /* set spi mode */
if (ret == -1) {
printf("can't set wr spi mode\n");
return -1;
}
//通过ioctl设置SPI数据位宽
ret = ioctl(fd_a7196, SPI_IOC_WR_BITS_PER_WORD, &bits); /* set spi bits per word */
if (ret == -1) {
printf("can't set bits per word\n");
return -1;
}
//通过ioctl设置SPI传输速率
ret = ioctl(fd_a7196, SPI_IOC_WR_MAX_SPEED_HZ, &speed); /* max speed hz */
if (ret == -1) {
printf("can't set max speed hz\n");
return -1;
}
return ret;
}
三、SPI读写操作函数
void SpiWriteByte(int fd_spi, uint8_t RegAddr)
{
int ret;
struct spi_ioc_transfer xfer[1];
uint8_t tx_buff[1];
uint8_t rx_buff[1];
tx_buff[0] = RegAddr;
memset(xfer,0,sizeof(struct spi_ioc_transfer));
xfer[0].tx_buf = (unsigned long)tx_buff;
xfer[0].rx_buf = (unsigned long)rx_buff;
xfer[0].len = 1;
xfer[0].speed_hz = speed;
xfer[0].bits_per_word = bits;
xfer[0].cs_change = 1;
ret = ioctl(fd_spi,SPI_IOC_MESSAGE(1),&xfer);
if(ret != xfer[0].len){
printf("can't xfer spi message(write byte)!,ret=%d\n",ret);
return;
}
}
void SpiWriteRegister(int fd_spi, uint8_t RegAddr, uint8_t RegVal)
{
int ret;
struct spi_ioc_transfer xfer[1];
uint8_t tx_buff[2];
uint8_t rx_buff[2];
memset(tx_buff,0,sizeof(tx_buff));
memset(rx_buff,0,sizeof(rx_buff));
tx_buff[0] = RegAddr;
tx_buff[1] = RegVal;
memset(xfer,0,sizeof(struct spi_ioc_transfer));
xfer[0].tx_buf = (unsigned long)tx_buff;
xfer[0].rx_buf = (unsigned long)rx_buff;
xfer[0].len = 2;
xfer[0].speed_hz = speed;
xfer[0].bits_per_word = bits;
xfer[0].cs_change = 1;
ret = ioctl(fd_spi,SPI_IOC_MESSAGE(1),&xfer);
if(ret != xfer[0].len){
printf("can't xfer spi message(write register)!,ret=%d\n",ret);
return;
}
}
void SpiWriteBuffer(int fd_spi, uint8_t RegAddr, uint8_t *buf, uint16_t size)
{
int ret;
struct spi_ioc_transfer xfer[2];
uint8_t tx_buff[1];
tx_buff[0] = RegAddr;
memset(xfer,0,2*sizeof(struct spi_ioc_transfer));
xfer[0].tx_buf = (unsigned long)tx_buff;
xfer[0].rx_buf = (unsigned long)tmpbuf;
xfer[0].len = 1;
xfer[0].speed_hz = speed;
xfer[0].bits_per_word = bits;
xfer[0].cs_change = 0;
xfer[1].tx_buf = (unsigned long)buf;
xfer[1].rx_buf = (unsigned long)tmpbuf;
xfer[1].len = size;
xfer[1].speed_hz = speed;
xfer[1].bits_per_word = bits;
xfer[1].cs_change = 1;
ret = ioctl(fd_spi,SPI_IOC_MESSAGE(2),&xfer);
if(ret != size+1){
printf("can't xfer spi message(write buffer)!,ret=%d\n",ret);
return;
}
}
uint8_t SpiReadByte(int fd_spi)
{
int ret;
struct spi_ioc_transfer xfer[1];
uint8_t tx_buff[1];
uint8_t rx_buff[1];
memset(tx_buff,0,sizeof(tx_buff));
memset(rx_buff,0,sizeof(rx_buff));
memset(xfer,0,sizeof(struct spi_ioc_transfer));
xfer[0].tx_buf = (unsigned long)tx_buff;
xfer[0].rx_buf = (unsigned long)rx_buff;
xfer[0].len = 1;
xfer[0].speed_hz = speed;
xfer[0].bits_per_word = bits;
xfer[0].cs_change = 1;
ret = ioctl(fd_spi,SPI_IOC_MESSAGE(1),&xfer);
if(ret != xfer[0].len){
printf("can't xfer spi message(read byte)!,ret=%d\n",ret);
return ret;
}
return rx_buff[0];
}
uint8_t SpiReadRegister(int fd_spi, uint8_t RegAddr)
{
int ret;
struct spi_ioc_transfer xfer[1];
uint8_t tx_buff[2];
uint8_t rx_buff[2];
memset(tx_buff,0,sizeof(tx_buff));
memset(rx_buff,0,sizeof(rx_buff));
tx_buff[0] = RegAddr;
tx_buff[1] = 0;
memset(xfer,0,sizeof(struct spi_ioc_transfer));
xfer[0].tx_buf = (unsigned long)tx_buff;
xfer[0].rx_buf = (unsigned long)rx_buff;
xfer[0].len = 2;
xfer[0].speed_hz = speed;
xfer[0].bits_per_word = bits;
xfer[0].cs_change = 1;
ret = ioctl(fd_spi,SPI_IOC_MESSAGE(1),&xfer);
if(ret != xfer[0].len){
printf("can't xfer spi message(read register)!,ret=%d\n",ret);
return ret;
}
return rx_buff[1];
}
void SpiReadBuffer(int fd_spi, uint8_t RegAddr, uint8_t *buf, uint16_t size)
{
int ret;
struct spi_ioc_transfer xfer[2];
uint8_t tx_buff[1];
uint8_t rx_buff[1];
tx_buff[0] = RegAddr;
memset(tmpbuf,0,512);
memset(xfer,0,2*sizeof(struct spi_ioc_transfer));
xfer[0].tx_buf = (unsigned long)tx_buff;
xfer[0].rx_buf = (unsigned long)rx_buff;
xfer[0].len = 1;
xfer[0].speed_hz = speed;
xfer[0].bits_per_word = bits;
xfer[0].cs_change = 0;
xfer[1].tx_buf = (unsigned long)tmpbuf;
xfer[1].rx_buf = (unsigned long)buf;
xfer[1].len = size;
xfer[1].speed_hz = speed;
xfer[1].bits_per_word = bits;
xfer[1].cs_change = 1;
ret = ioctl(fd_spi,SPI_IOC_MESSAGE(2),&xfer);
if(ret != (1+size)){
printf("can't xfer spi message(read buffer)!,ret=%d\n",ret);
return;
}
}