分类: Beaglebone Black2013-11-24 18:21 678人阅读 评论(6) 收藏 举报
 

目录(?)[+]

 

SPI是可以全双工通信的一种串行总线,两个设备之间双向通信的话一般使用3根线:SCLK,MISO,MOSI,多个设备之间双向通信的话,每个设备还需要再加上一根地址线CSn。相比之下I2C只能半双工,而且一般需要上拉电阻,但无论几个设备,都只需要2根线。更多基础知识请谷歌百度。

Beaglebone Black使用的AM3359芯片上有两个SPI,但SPI1连接到了板子的HDMI芯片上,所以除非禁用HDMI,否则我们只能使用SPI0。本文将利用自带的spidev驱动使能SPI0,并进行一下简单的验证。

配置device tree

首先我们用我在《使用BBB的I2C》这篇文章中使用的方法检验一下SPI相关的引脚功能是否配置正确。检查结果是,不正确,也就是说SPI默认是没有启用的,新版arm linux配置硬件的方式是利用device tree,所以我们必须要配置一个device tree来启用它。我们先到 /lib/firmware 目录中看看有没有现成的device tree source (.dts)文件可供使用。我们发现有一个BB-SPI0-00A0.dts。内容如下

  1. /dts-v1/;
  2. /plugin/;
  3. / {
  4. compatible = "ti,beaglebone", "ti,beaglebone-black";
  5. /* identification */
  6. part-number = "BB-SPI0";
  7. version = "00A0";
  8. /* state the resources this cape uses */
  9. exclusive-use =
  10. /* the pin header uses */
  11. "P9.17",    /* spi0_cs0 */
  12. "P9.18",    /* spi0_d1 */
  13. "P9.21",    /* spi0_d0 */
  14. "P9.22",    /* spi0_sclk */
  15. /* the hardware ip uses */
  16. "spi0";
  17. fragment@0 {
  18. target = <&am33xx_pinmux>;
  19. __overlay__ {
  20. /* default state has all gpios released and mode set to uart1 */
  21. bb_spi0_pins: pinmux_bb_spi0_pins {
  22. pinctrl-single,pins = <
  23. 0x150 0x30  /* spi0_sclk.spi0_sclk, INPUT_PULLUP | MODE0 */
  24. 0x154 0x30  /* spi0_d0.spi0_d0, INPUT_PULLUP | MODE0 */
  25. 0x158 0x10  /* spi0_d1.spi0_d1, OUTPUT_PULLUP | MODE0 */
  26. 0x15c 0x10  /* spi0_cs0.spi0_cs0, OUTPUT_PULLUP | MODE0 */
  27. >;
  28. };
  29. };
  30. };
  31. fragment@1 {
  32. target = <&spi0>; /* spi0 is numbered correctly */
  33. __overlay__ {
  34. status = "okay";
  35. pinctrl-names = "default";
  36. pinctrl-0 = <&bb_spi0_pins>;
  37. #address-cells = <1>;
  38. #size-cells = <0>;
  39. /* add any spi devices connected here */
  40. /* note that you can do direct SPI via spidev now */
  41. // commented out example of an adafruit 1.8" TFT display
  42. // from firmare/capes/cape-bone-adafruit-lcd-00A0.dts
  43. // lcd@0 {
  44. //  #address-cells = <1>;
  45. //  #size-cells = <0>;
  46. //
  47. //  compatible = "adafruit,tft-lcd-1.8-red", "sitronix,st7735";
  48. //  reg = <0>;
  49. //
  50. //  spi-max-frequency = <8000000>;
  51. //  spi-cpol;
  52. //  spi-cpha;
  53. //
  54. //  pinctrl-names = "default";
  55. //  pinctrl-0 = <&bone_adafruit_lcd_pins>;
  56. //
  57. //  st7735-rst = <&gpio4 19 0>;
  58. //  st7735-dc = <&gpio4 21 0>;
  59. // };
  60. };
  61. };
  62. };

从这个文件里我们能得到很多信息(我在此唠叨两句,也算跟大家分享一下我学习的过程),首先我们从exclusive-use这一部分能看出来AM3359芯片对SPI引脚的命名是跟一般不太一样的,它没用MISO和MOSI,而是D0和D1。通过查询4000页手册我们得知,原来是因为这两个引脚的功能是可以通过配置寄存器来互换的。默认的对应方式如下

再接着看,发现有一句注释

  1. /* note that you can do direct SPI via spidev now */

这个spidev就是我们要用的spi驱动,然后谷歌一下它的用法就可以了。再下面有一些被注释掉的东西,是要根据不同设备来替换的。

(以下操作都在Beaglebone上进行)

我们把自带的文件复制一份,保存为 BB-SPI0-01-00A0.dts ,然后增加一个节点,内容如下(就是原文件中注释部分要替换的内容)

  1. spidev@0 {
  2. spi-max-frequency = <24000000>;
  3. reg = <0>;
  4. compatible = "linux,spidev";
  5. };

保存以后编译这个dts文件

  1. dtc -O dtb -o BB-SPI0-01-00A0.dtbo -b 0 -@ BB-SPI0-01-00A0.dts

然后把生成的.dtbo文件放到/lib/firmware目录中

  1. cp BB-SPI0-01-00A0.dtbo /lib/firmware/

然后把它“插”到“插槽”中(请看我的博文《聊聊Beaglebone Black的cape和device tree overlay》)

  1. echo BB-SPI0-01 > /sys/devices/bone_capemgr.*/slots

OK,这时我们进入/dev目录中就会发现比原来多了一个设备 spidev1.0 ,说明device tree配置没有问题,该设备已成功加载。

使用SPI

因为我手边没有SPI设备,所以我把D0和D1也就是P9.18和P9.21这两个引脚连接起来进行自发自收,如果收到了发送的数据即成功。时钟线就不必管了,因为自己跟自己的时钟肯定是同步的。
 
测试程序使用的是linux自带的一个spidev_test.c程序(下载地址是 https://www.kernel.org/doc/Documentation/spi/,不过还是建议直接把整个kernel下载下来比较方便搜索查询)。这个程序的内容就是发送一串16进制数,然后 printf 接收到的内容(不知道这串数有没有什么别的含义)。
 
下面把这个文件传到Beaglebone上,用gcc编译一下,生成可执行文件spidev_test。假设现在就在这个文件的目录下,那么我们输入
  1. ./spidev_test -D /dev/spidev1.0

来进行测试。得到输出

  1. spi mode: 0
  2. bits per word: 8
  3. max speed: 500000 Hz (500 KHz)
  4. FF FF FF FF FF FF
  5. 40 00 00 00 00 95
  6. FF FF FF FF FF FF
  7. FF FF FF FF FF FF
  8. FF FF FF FF FF FF
  9. DE AD BE EF BA AD
  10. F0 0D

说明测试成功了。否则会输出一串FF。

 

为什么dts文件要那样改?

刚刚我在自带的BB-SPI0-00A0.dts文件中加了一个节点,然后向其中加了几个属性,SPI0就能用了。增加一个节点还能够理解,但为什么要加这几个属性?这个问题我想了几天也没想得很清楚。不过我知道的是,这3个属性缺一不可。
 
其中compatible属性是每个节点必须有的,它的作用是将这个设备和某个驱动进行绑定。比如这里就是将这个spi设备与 linux -> spidev 这个驱动绑定。我把逗号换成了箭头,是因为我觉得其实这个逗号表达的是从属关系,用箭头更合适。但是,我在kernel文件中翻遍了也没找到哪里有“linux,spidev”这样的字眼。spidev驱动倒是找到了,而且在这个驱动文件中发现了如下内容
  1. static const struct of_device_id spidev_dt_ids[] = {
  2. { .compatible = "rohm,dh2228fv" },
  3. {},
  4. };

我试着把BB-SPI0-01-00A0.dts里的 compatible 值换成 “rohm,dh2228fv”,结果居然也成功了!这似乎说明以后如果我们知道要用哪个驱动的话,到驱动文件里搜索compatible找到相应内容就可以了。不过,我遗憾地发现大部分驱动文件里都没有这个属性。可能只有一些硬件外设的驱动,或者是别的公司做的驱动里才会有。所以,我又迷惘了……

[转]使用Beaglebone Black的SPI的更多相关文章

  1. Enable SPI 1.0 and 1.1 with device tre overlays on BeagleBone

    For most people the above image means absolutely nothing, but for that one guy that has been searchi ...

  2. Beaglebone Black – 连接 GY-91 MPU9250+BMP280 九轴传感器(2)

    这次用 SPI.BBB 有两套 SPI 接口可用,两套都是默认 disable,需要用 overlay 方式启用,即: echo BB-SPIDEV0 > /sys/devices/bone_c ...

  3. Beaglebone Black–I2C 接 BMP280 获取当前温度

    我有两个含温度传感的模块,一个是AOSONG 奥松电子的 AM2320 温度湿度,另一个是九轴里面的 Bosch BMP280.由于 AM2320 用 I2C MODBUS,直接用 I2C Tools ...

  4. BeagleBone Black项目实训手册(大学霸内部资料)

    BeagleBone Black项目实训手册(大学霸内部资料) 介绍:本教程是<BeagleBone Black快速入门教程>的后续教程.本教程以项目操作为主,讲解LED项目.声音项目.传 ...

  5. 三大主流开源硬件对比:Arduino vs BeagleBone vs Raspberry Pi

    个人总结: Arduino就是个AVR单片机,个人觉得更适合玩电子的,社区也很活跃. BeagleBone是ARM Cortex-A8,属于嵌入式,价格高于Pi,但是许多方面拥有超越 Pi 的优 势, ...

  6. 转:从BeagleBone谈AM335x硬件系统设计

    链接:http://blog.chinaunix.net/uid-730738-id-3266690.html    作者:chenzhufly 从BeagleBone谈AM335x硬件系统设计 日期 ...

  7. Beaglebone Black教程Beaglebone Black的引脚分配

    Beaglebone Black教程Beaglebone Black的引脚分配 Beaglebone Black的引脚分配 绝大多数的微型开发平台都提供了一些称为GPIO的输入输出端口.这些端口可以让 ...

  8. BeagleBone Black Industrial 工业版介绍

    前言 在电子发烧友论坛看到有Beaglebone Black Industrial版的试用,这里介绍一下这块开发板. BBB是开源硬件,原理图.BOM等都开放下载,所以也有诸多兼容板. BBB兼容产品 ...

  9. 嵌入式平台选择:树莓派 or BeagleBone Black(BBB)

    原文链接: Michael Leonard 翻译: 极客范- 小道空空 译文链接: http://www.geekfan.net/5246/ 嵌入式平台选择:树莓派 or BeagleBone Bla ...

随机推荐

  1. dojo自定义Widget

    使dojo AMD规范进行widget 定义,开始的时候一直找不到自己定义的widget模块的位置,经过探索,总算有收获,我这个人有毛病,脑子里不允许有一些想不通的问题,一旦有了问题,就非常难受,心里 ...

  2. ruby Mixin用法

    module My NA="China" attr:name attr:age def set_name(name) @name=name end def get_name ret ...

  3. php加速缓存Xcache的安装与配置

    安装环境:centos 6.5 32bit  php5.5.7 nginx1.6.0 [root@localhost opt]# wget http://xcache.lighttpd.net/pub ...

  4. [liu yanling]软件开发的过程按阶段划分有:单元测试 集成测试 系统测试 验收测试

    从软件开发的过程按阶段划分有:单元测试 集成测试 系统测试 验收测试测试过程按 4 个步骤进行,概念内容如下:单元测试:单元测试是对软件基本组成单元(如函数.类的方法等)进行的测试.集成测试:集成测试 ...

  5. curl检查远程文件是否存在

    size_t processdata(void *buffer, size_t size, size_t nmemb, void *user_p) { //写一个空的写函数 return nmemb; ...

  6. 【原】实战-Java如何使用Redis

    实战-Java如何使用Redis Redis的Client支持的语言非常丰富,如下: ActionScript Bash C C# C++ Clojure Common Lisp Crystal D ...

  7. 从打车软件你能想到多少?盈利模式?商机?大数据?移动互联网蛋糕?生活方式改变withApp?

    物联网.云服务.大数据.. 淘宝.12306.卡通...一个产品改变一次生活方式. 打车app,无疑是改变生活方式的又一个产品.从打车软件,你能看到什么? 个人认为,打车软件值得各种投资方斥资,最重要 ...

  8. python —print

    今天开始学python了,“装X”安装了最新版本python 3.4.1 然后,print “hello world!" 就出错了... 一搜原来... python v3.0以后的版本pr ...

  9. [二]java运行原理

    public class HelloWorld{ public static void main(String args[]){ System.out.println("hello" ...

  10. 在 windows 上面安装 tensorflow

    这个是 tensorflow 官网地址, https://www.tensorflow.org/get_started/os_setup#pip_installation_on_windows 上面有 ...