spi 子系统

/dev/spidev0.0对应ESAM,   /dev/spidev1.2对应ATT7022E

[cpp] view plain copy

  1. #include <stdint.h>
  2. #include <unistd.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <getopt.h>
  6. #include <fcntl.h>
  7. #include <sys/ioctl.h>
  8. #include <linux/types.h>
  9. #include <linux/spi/spidev.h>
  10. #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
  11. static void pabort(const char *s)
  12. {
  13. perror(s);
  14. abort();
  15. }
  16. /*   /dev/spidev0.0对应ESAM,   /dev/spidev1.2对应ATT7022E */
  1. static const char *device = "/dev/spidev1.2";  /
  2. static uint8_t mode;
  3. static uint8_t bits = 8;
  4. static uint32_t speed = 500000;
  5. static uint16_t delay;
  6. static void transfer(int fd)
  7. {
  8. int ret;
  9. uint8_t tx[] = {    //要发送的数据数组
  10. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  11. 0x40, 0x00, 0x00, 0x00, 0x00, 0x95,
  12. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  13. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  14. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  15. 0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD,
  16. 0xF0, 0x0D,
  17. };
  18. uint8_t rx[ARRAY_SIZE(tx)] = {0, }; //接收的数据数据
  19. struct spi_ioc_transfer tr = {  //声明并初始化spi_ioc_transfer结构体
  20. .tx_buf = (unsigned long)tx,
  21. .rx_buf = (unsigned long)rx,
  22. .len = ARRAY_SIZE(tx),
  23. .delay_usecs = delay,
  24. .speed_hz = speed,
  25. .bits_per_word = bits,
  26. };
  27. //SPI_IOC_MESSAGE(1)的1表示spi_ioc_transfer的数量
  28. ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);   //ioctl默认操作,传输数据
  29. if (ret < 1)
  30. pabort("can‘t send spi message");
  31. for (ret = 0; ret < ARRAY_SIZE(tx); ret++) { //打印接收缓冲区
  32. if (!(ret % 6))     //6个数据为一簇打印
  33. puts("");
  34. printf("%.2X ", rx[ret]);
  35. }
  36. puts("");
  37. }
  38. static void print_usage(const char *prog)   //参数错误则打印帮助信息
  39. {
  40. printf("Usage: %s [-DsbdlHOLC3]\n", prog);
  41. puts("  -D --device   device to use (default /dev/spidev1.1)\n"
  42. "  -s --speed    max speed (Hz)\n"
  43. "  -d --delay    delay (usec)\n"
  44. "  -b --bpw      bits per word \n"
  45. "  -l --loop     loopback\n"
  46. "  -H --cpha     clock phase\n"
  47. "  -O --cpol     clock polarity\n"
  48. "  -L --lsb      least significant bit first\n"
  49. "  -C --cs-high  chip select active high\n"
  50. "  -3 --3wire    SI/SO signals shared\n");
  51. exit(1);
  52. }
  53. static void parse_opts(int argc, char *argv[])
  54. {
  55. while (1) {
  56. static const struct option lopts[] = {  //参数命令表
  57. { "device",  1, 0, ‘D‘ },
  58. { "speed",   1, 0, ‘s‘ },
  59. { "delay",   1, 0, ‘d‘ },
  60. { "bpw",     1, 0, ‘b‘ },
  61. { "loop",    0, 0, ‘l‘ },
  62. { "cpha",    0, 0, ‘H‘ },
  63. { "cpol",    0, 0, ‘O‘ },
  64. { "lsb",     0, 0, ‘L‘ },
  65. { "cs-high", 0, 0, ‘C‘ },
  66. { "3wire",   0, 0, ‘3‘ },
  67. { "no-cs",   0, 0, ‘N‘ },
  68. { "ready",   0, 0, ‘R‘ },
  69. { NULL, 0, 0, 0 },
  70. };
  71. int c;
  72. c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR", lopts, NULL);
  73. if (c == -1)
  74. break;
  75. switch (c) {
  76. case ‘D‘:   //设备名
  77. device = optarg;
  78. break;
  79. case ‘s‘:   //速率
  80. speed = atoi(optarg);
  81. break;
  82. case ‘d‘:   //延时时间
  83. delay = atoi(optarg);
  84. break;
  85. case ‘b‘:   //每字含多少位
  86. bits = atoi(optarg);
  87. break;
  88. case ‘l‘:   //回送模式
  89. mode |= SPI_LOOP;
  90. break;
  91. case ‘H‘:   //时钟相位
  92. mode |= SPI_CPHA;
  93. break;
  94. case ‘O‘:   //时钟极性
  95. mode |= SPI_CPOL;
  96. break;
  97. case ‘L‘:   //lsb 最低有效位
  98. mode |= SPI_LSB_FIRST;
  99. break;
  100. case ‘C‘:   //片选高电平
  101. mode |= SPI_CS_HIGH;
  102. break;
  103. case ‘3‘:   //3线传输模式
  104. mode |= SPI_3WIRE;
  105. break;
  106. case ‘N‘:   //没片选
  107. mode |= SPI_NO_CS;
  108. break;
  109. case ‘R‘:   //从机拉低电平停止数据传输
  110. mode |= SPI_READY;
  111. break;
  112. default:    //错误的参数
  113. print_usage(argv[0]);
  114. break;
  115. }
  116. }
  117. }
  118. int main(int argc, char *argv[])
  119. {
  120. int ret = 0;
  121. int fd;
  122. parse_opts(argc, argv); //解析传递进来的参数
  123. fd = open(device, O_RDWR);  //打开设备文件
  124. if (fd < 0)
  125. pabort("can‘t open device");
  126. /*
  127. * spi mode //设置spi设备模式
  128. */
  129. ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);    //写模式
  130. if (ret == -1)
  131. pabort("can‘t set spi mode");
  132. ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);    //读模式
  133. if (ret == -1)
  134. pabort("can‘t get spi mode");
  135. /*
  136. * bits per word    //设置每个字含多少位
  137. */
  138. ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);   //写 每个字含多少位
  139. if (ret == -1)
  140. pabort("can‘t set bits per word");
  141. ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);   //读 每个字含多少位
  142. if (ret == -1)
  143. pabort("can‘t get bits per word");
  144. /*
  145. * max speed hz     //设置速率
  146. */
  147. ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);   //写速率
  148. if (ret == -1)
  149. pabort("can‘t set max speed hz");
  150. ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);   //读速率
  151. if (ret == -1)
  152. pabort("can‘t get max speed hz");
  153. //打印模式,每字多少位和速率信息
  154. printf("spi mode: %d\n", mode);
  155. printf("bits per word: %d\n", bits);
  156. printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);
  157. transfer(fd);   //传输测试
  158. close(fd);  //关闭设备
  159. return ret;
  160. }
时间: 2024-12-18 01:48:26

spi 子系统的相关文章

Linux下spi驱动开发

转载至:http://www.embedu.org/Column/Column367.htm 作者:刘洪涛,华清远见嵌入式学院讲师. 一.概述 基于子系统去开发驱动程序已经是linux内核中普遍的做法了.前面写过基于I2C子系 统的驱动开发.本文介绍另外一种常用总线SPI的开发方法.SPI子系统的开发和I2C有很多的相似性,大家可以对比学习.本主题分为两个部分叙述,第一 部分介绍基于SPI子系统开发的理论框架:第二部分以华清远见教学平台FS_S5PC100上的M25P10芯片为例(内核版本2.6

SPI在linux3.14.78 FS_S5PC100(Cortex A8)和S3C2440上驱动移植(deep dive)

由于工作的原因,对SPI的理解最为深刻,也和SPI最有感情了,之前工作都是基于OSEK操作系统上进行实现,也在US/OS3上实现过SPI驱动的实现和测试,但是都是基于基本的寄存器操作,没有一个系统软件架构的思想,感觉linux SPI驱动很强大,水很深,废话少说,SPI总线上有两类设备:一类是主机端,通常作为SOC系统的一个子模块出现,比如很多嵌入式MPU中都常常包含SPI模块.一类是从机被控端,例如一些SPI接口的Flash.传感器等等.主机端是SPI总线的控制者,通过使用SPI协议主动发起S

Linux SPI驱动设计

1. SPI总线结构 SPI串行外设接口,是一种高速的,全双工,同步的通信总线.采用主从模式架构,支持多个slave,一般仅支持单Master SPI接口共有4根信号线,分别是: 设备选择线(SS).时钟线(SCK).串行输出数据线(MOSI).串行输入数据线(MISO). 2. 数据传输过程 主节点通过MOSI线输出数据,从节点在SIMO处从主节点读取数据.同时,也通过SMOI输出MSB(最高位), 主节点会在MISO处读取从节点的数据,整个过程将一直持续,直至交换完所有的数据. 3. 总线时

Linux驱动修炼之道-SPI驱动框架源码分析(上)【转】

转自:http://blog.csdn.net/lanmanck/article/details/6895318 SPI驱动架构,以前用过,不过没这个详细,跟各位一起分享: 来自:http://blog.csdn.net/woshixingaaa/article/details/6574215 SPI协议是一种同步的串行数据连接标准,由摩托罗拉公司命名,可工作于全双工模式.相关通讯设备可工作于m/s模式.主设备发起数据帧,允许多个从设备的存在.每个从设备 有独立的片选信号,SPI一般来说是四线串

Linux Spi驱动移植小结

2012-01-07 22:21:29 效果图: 理论学习后,主要是linux中spi子系统设备框架的了解后,主控制器与设备分离的思想,那么我要开始动手了. 1,  make menuconfig添加spi配置 2,platform_driver及platform_device数据结构都有了.于是在mach-tq2440.c中tq2440_devices[]结构添加里         &s3c_device_spi1,//by apple 3,接着开始make zImage. 出错,发现串口信息

spi-mem: 为SPI存储器生态系统带来一些一致性

在本文中,我们将介绍关于spi-mem Linux内核框架的工作,该框架将允许在SPI NOR设备和常规SPI设备以及SPI NAND设备上复用SPI控制器驱动程序. 从SPI到双线.四线.八线SPI 在过去,SPI是一个简单的协议,总线上的所有设备只共享3根信号线: MISO: Master In Slave Out,主设备输入从设备输出线 MOSI: Master Out Slave In,主设备输出从设备输入线 SCLK: Serial Clock,时钟线 另外每个设备有一个独立信号线,用

linux内核中有哪些子系统(框架)呢?

1. RTC子系统 2. Remote Processor子系统 3. Remote Processor Message子系统 4. SCSI子系统 5. SCSI Target子系统 6. Security子系统 7. SOC-CAMERA V4L2子系统 8. SOUNDWIRE子系统 9. SPI NOR子系统 10. SPI子系统 11. SPMI 子系统12. STAGING 子系统13. SWIOTLB 子系统14. TEE 子系统15. TURBOCHANNEL 子系统16. UL

SPI(1)——Documentation/spi/spi_summary.txt翻译

Linux内核SPI支持概述==================================== 02 - 2012 1.什么是SPI?------------ "Serial Peripheral Interface" (SPI) 是同步四线串行接口,用于将微控制器连接到传感器,存储器和外围设备的链路.这是一个简单的“事实上的”标准,并不足以获得标准化机构. SPI使用主/从配置. 三条信号线中有一个是时钟(SCK,通常在10 MHz的数量级),以及具有"Master

基于tiny4412的Linux内核移植 -- 设备树的展开

作者信息 作者: 彭东林 邮箱:[email protected] QQ:405728433 平台简介 开发板:tiny4412ADK + S700 + 4GB Flash 要移植的内核版本:Linux-4.4.0 (支持device tree) u-boot版本:友善之臂自带的 U-Boot 2010.12 (为支持uImage启动,做了少许改动) busybox版本:busybox 1.25 交叉编译工具链: arm-none-linux-gnueabi-gcc (gcc version 4