您的位置:首页 > 其它

应用程序和驱动中使用SPI设备的流程

2017-03-02 11:26 295 查看
编写SPI设备驱动有两种方法。一种是利用系统给我们提供的spidev.c来实现一个spi适配器的设备文件。然后通过在应用层操作spi适配器来控制spi设备。另一种是为spi设备,独立编写一个设备驱动。注意:在后一种情况下,是不需要使用spidev.c的。

前一种方法也就是说只要系统实现了spi适配器的驱动并生成了设备文件, 那么挂在其上面的spi设备也可以在应用层直接通过操作这个设备文件来间接控制这个spi设备, 这样就省去了专门为这个设备编写驱动的麻烦。本文将详细描述在应用层和驱动层分别控制spi设备的流程。

关于在应用层如何使用spidev驱动的问题, 可以参考源码的documenation/spi目录下的文档, 其中spidev_test.c就是一个测试程序,可以参考。

下面将结合本人工作中实现的一个例子来介绍应用层使用spidev的流程。实际上流程比较简单:打开设备文件 -> 配置设备 -> 读写设备 -> 关闭设备文件。

1.      打开设备文件:

#defineICCARD_DEVICE_FILE   ("/dev/spidev0.0")      /*spi controller device file*/

/*1.open lcd device*/

fd_iccard= open(ICCARD_DEVICE_FILE, O_WRONLY);

if(fd_iccard< 0) {

           LOGE("can'topen ICCARD device file");

           return0;

         }

跟打开普通的文件没有什么区别。

2.      配置设备:

static uint8_ticcard_spi_mode   = SPI_MODE_3;    /*spi operation mode*/

/*2.initialize SPI controller*/

/*

 * spi mode

 */

ret= ioctl(fd_iccard, SPI_IOC_WR_MODE, &iccard_spi_mode);

if (ret< 0) {

           LOGE("can'tset spi mode");

           gotoinit_failed;

}

 

ret =ioctl(fd_iccard, SPI_IOC_RD_MODE, &iccard_spi_mode);

if (ret< 0) {

           LOGE("can'tget spi mode");

           gotoinit_failed;

}

 

/*

 * bits per word

 */

ret =ioctl(fd_iccard, SPI_IOC_WR_BITS_PER_WORD, &iccard_spi_bits);

if (ret< 0) {

           LOGE("can'tset bits per word");

           gotoinit_failed;

}

ret =ioctl(fd_iccard, SPI_IOC_RD_BITS_PER_WORD, &iccard_spi_bits);

if (ret< 0) {

           LOGE("can'tget bits per word");

           gotoinit_failed;

}

 

/*

 * max speed hz

 */

ret =ioctl(fd_iccard, SPI_IOC_WR_MAX_SPEED_HZ, &iccard_spi_speed);

if (ret< 0) {

           LOGE("can'tset max speed hz");

           gotoinit_failed;

}

ret =ioctl(fd_iccard, SPI_IOC_RD_MAX_SPEED_HZ, &iccard_spi_speed);

if (ret< 0) {

           LOGE("can'tget max speed hz");

           gotoinit_failed;

    }

通过ioctl系统调用设置spi的工作模式(4种模式之一, 参考SPI协议),每个传输单元的位数,最大工作频率等。

3.      读写设备:

static structspi_ioc_transfer iccard_spi_msg = {  /*spi message for transfer*/

.speed_hz = 2000000,

.bits_per_word = 8,

.delay_usecs = 0,

};   /*每个传输必须封装成这种格式*/

iccard_spi_msg.tx_buf= (unsigned long) NULL;  /*我们的设备只需要读, 所以没有tx_buf*/

 

while(index< ICCARD_DATA_LEN)

{

           iccard_spi_msg.rx_buf = (unsignedlong)&ic_data_ptr[index]; /*读到的数据缓存*/

           iccard_spi_msg.len= 1;  /*每次读1个字节*/

           ret= ioctl(fd_iccard, SPI_IOC_MESSAGE(1), &iccard_spi_msg);

           if(ret < 0)

           {

                    LOGE("[AARON]read iccard failed");

                    return0;

           }

 

           index++;

      }

同样的,通过ioctl系统调用,发送SPI_IOC_MESSAGE命令给设备,来读取或写入数据。

4.      关闭设备:

close(fd_iccard);

 

如上描述, spidev给开发人员提供了一种比较简单的操作SPI设备的方式, 开发人员可以不用会编写spi驱动就能使用spi设备。

·~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

关于spi驱动的链接

【推荐】 Linux spi驱动分析(三)----spiddev分析79530112013-12-30 
Linux spi驱动分析(二)----SPI核心(bus、device_driver和device)3670052013-12-11 
Linux spi驱动分析(四)----SPI设备驱动(W25Q32BV)1080510112013-12-06 
Linux spi驱动分析(一)----总线驱动8524172013-11-13 
mini2440 SPI驱动移植2754012013-07-12 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: