Hi3518EV200学习记录之用户态SPI

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

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值