freescale spi driver

1:配置管脚为SPI功能

在board-mx6q_sabresd.h的最后添加,复制被重定义

(以添加SPI2为例)

       

[cpp]  view plain copy
  1. <span style="font-size:18px;">        MX6Q_PAD_EIM_CS0__ECSPI2_SCLK,  
  2.         MX6Q_PAD_EIM_CS1__ECSPI2_MOSI,  
  3.         MX6Q_PAD_EIM_OE__ECSPI2_MISO,  
  4.         MX6Q_PAD_CSI0_DAT11__ECSPI2_SS0 ,  
  5. </span>  


之后再板级文件board-mx6q_sabresd.c中将有相关函数对管脚进行统一初始化。

完成寄存器配置的工作。

[cpp]  view plain copy
  1. <span style="font-size:18px;">  mxc_iomux_v3_setup_multiple_pads(mx6q_sabresd_pads,  
  2.         ARRAY_SIZE(mx6q_sabresd_pads));  
  3.   
  4.     mxc_iomux_v3_setup_multiple_pads(mx6q_sabresd_cstm_tq_pads,\  
  5.         ARRAY_SIZE(mx6q_sabresd_cstm_tq_pads));</span>  

2:在板级文件board-mx6q_sabresd.c中添加以下代码

将匹配到driver/spi/spidev.c文件中的驱动源码

2.1完成SPI master的注册

SPI2片选管脚宏定义:

[cpp]  view plain copy
  1. <span style="font-size:14px;">#define SABRESD_ECSPI2_CS0 IMX_GPIO_NR(5, 29)</span>  


添加相关结构体

[cpp]  view plain copy
  1. <span style="font-size:14px;">static int mx6q_marsboard_spi1_cs[] = {  
  2.         SABRESD_ECSPI2_CS0,  
  3. };  
  4. </span>  


 

[cpp]  view plain copy
  1. <span style="font-size:14px;">static const struct spi_imx_master mx6q_sabresd_spi2_data __initconst = {  
  2.         .chipselect = mx6q_marsboard_spi2_cs,  
  3.         .num_chipselect = ARRAY_SIZE(mx6q_marsboard_spi1_cs),  
  4. };  
  5. </span>  


 

2.2在spi 总线上匹配spi2的驱动文件

mx6q平台有2路spi资源,0/1,其中的bus_num则为挂载驱动的总线选择。


[cpp]  view plain copy
  1. <span style="font-size:18px;"><span style="font-size:14px;">static struct mtd_partition imx6_sabrelite_spi_nor_partitions[] = {  
  2.  {  
  3.   .name = "bootloader",  
  4.   .offset = 0,  
  5.   .size = 0x00100000,  
  6.  },  
  7.  {  
  8.   .name = "kernel",  
  9.   .offset = MTDPART_OFS_APPEND,  
  10.   .size = MTDPART_SIZ_FULL,  
  11.  },  
  12. };  
  13.   
  14.   
  15. static struct flash_platform_data imx6_sabrelite__spi_flash_data = {  
  16.  .name = "spidev",  / /匹配原则。  
  17.  .parts = imx6_sabrelite_spi_nor_partitions,  
  18.  .nr_parts = ARRAY_SIZE(imx6_sabrelite_spi_nor_partitions),  
  19.  .type = "sst25vf016b",  
  20. };  
  21.   
  22.   
  23.   
  24.   
  25. static struct spi_board_info imx6_sabrelite_spi_nor_device[] __initdata = {  
  26.  {  
  27.   .modalias = "spidev",  
  28.   .max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */  
  29.   .bus_num = 1,    //设备挂载第几号spi总线上  
  30.   .chip_select = 0,  
  31.   .platform_data = &imx6_sabrelite__spi_flash_data,  
  32.  },  
  33. };  
  34.   
  35.   
  36. spi_register_board_info(imx6_sabrelite_spi_nor_device,  
  37. ARRAY_SIZE(imx6_sabrelite_spi_nor_device));  
  38.   
  39. imx6q_add_ecspi(0, &mx6q_sabrelite_spi2_data);  
  40.   
  41.   
  42.   
  43.   
  44.   
  45.   
  46. </span>   
  47. </span>  

 

3:内核配置

 

查看spidev.c文件目录下的Kconfig以及Makefile得知内核驱动的添加方法

 

freescale spi driver_第1张图片

freescale spi driver_第2张图片

选择蓝色部分选项,将spidev.c文件添加到内核中。

freescale spi driver_第3张图片

 

4:查看开发板/sys/bus/spi/drivers/spidev目录

 

在/dev下生成设备文件/dev/spidev1.0

 

5:使用freescale官方的bsp包中的spi测试程序对接口进行测试

[cpp]  view plain copy
  1. <span style="font-size:12px;">/* 
  2.  * SPI testing utility (using spidev driver) 
  3.  * 
  4.  * Copyright (c) 2007  MontaVista Software, Inc. 
  5.  * Copyright (c) 2007  Anton Vorontsov <[email protected]> 
  6.  * 
  7.  * This program is free software; you can redistribute it and/or modify 
  8.  * it under the terms of the GNU General Public License as published by 
  9.  * the Free Software Foundation; either version 2 of the License. 
  10.  * 
  11.  * Cross-compile with cross-gcc -I/path/to/cross-kernel/include 
  12.  */  
  13.   
  14. #include <stdint.h>  
  15. #include <unistd.h>  
  16. #include <stdio.h>  
  17. #include <stdlib.h>  
  18. #include <getopt.h>  
  19. #include <fcntl.h>  
  20. #include <sys/ioctl.h>  
  21. #include <linux/types.h>  
  22. #include <linux/spi/spidev.h>  
  23.   
  24. #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))  
  25.   
  26. static void pabort(const char *s)  
  27. {  
  28.     perror(s);  
  29.     abort();  
  30. }  
  31.   
  32. static const char *device = "/dev/spidev1.0";  
  33. static uint8_t mode;  
  34. static uint8_t bits = 8;  
  35. static uint32_t speed = 500000;  
  36. static uint16_t delay;  
  37.   
  38. static void transfer(int fd)  
  39. {  
  40.     int ret;  
  41.     uint8_t tx[] = {  
  42.         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  
  43.         0x40, 0x00, 0x00, 0x00, 0x00, 0x95,  
  44.         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  
  45.         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  
  46.         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  
  47.         0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD,  
  48.         0xF0, 0x0D,  
  49.     };  
  50.     uint8_t rx[ARRAY_SIZE(tx)] = {0, };  
  51.     struct spi_ioc_transfer tr = {  
  52.         .tx_buf = (unsigned long)tx,  
  53.         .rx_buf = (unsigned long)rx,  
  54.         .len = ARRAY_SIZE(tx),  
  55.         .delay_usecs = delay,  
  56.         .speed_hz = speed,  
  57.         .bits_per_word = bits,  
  58.     };  
  59.   
  60.     ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);  
  61.     if (ret < 1)  
  62.         pabort("can't send spi message");  
  63.   
  64.     for (ret = 0; ret < ARRAY_SIZE(tx); ret++) {  
  65.         if (!(ret % 6))  
  66.             puts("");  
  67.         printf("%.2X ", rx[ret]);  
  68.     }  
  69.     puts("");  
  70. }  
  71.   
  72.   
  73. int main(int argc, char *argv[])  
  74. {  
  75.     int ret = 0;  
  76.     int fd;  
  77.   
  78.     //parse_opts(argc, argv); /* for what ,unknow*/  
  79.   
  80.     fd = open(device, O_RDWR);  
  81.     if (fd < 0)  
  82.         pabort("can't open device");  
  83.   
  84.     /* 
  85.      * spi mode 
  86.      */  
  87.     ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);  
  88.     if (ret == -1)  
  89.         pabort("can't set spi mode");  
  90.   
  91.     ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);  
  92.     if (ret == -1)  
  93.         pabort("can't get spi mode");  
  94.   
  95.     /* 
  96.      * bits per word 
  97.      */  
  98.     ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);  
  99.     if (ret == -1)  
  100.         pabort("can't set bits per word");  
  101.   
  102.     ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);  
  103.     if (ret == -1)  
  104.         pabort("can't get bits per word");  
  105.   
  106.     /* 
  107.      * max speed hz 
  108.      */  
  109.     ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);  
  110.     if (ret == -1)  
  111.         pabort("can't set max speed hz");  
  112.   
  113.     ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);  
  114.     if (ret == -1)  
  115.         pabort("can't get max speed hz");  
  116.   
  117.     printf("spi mode: %d\n", mode);  
  118.     printf("bits per word: %d\n", bits);  
  119.     printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);  
  120.   
  121.     transfer(fd);  
  122.   
  123.     close(fd);  
  124.   
  125.     return ret;  
  126. }  
  127. </span>  


 

执行应用程序,可以看到时序模式(spi 4种时序模式第0种),时钟频率等参数。

freescale spi driver_第4张图片

 短路则与输入一致

你可能感兴趣的:(SPI)