SPI设备树处理过程

SPI设备树处理过程



参考资料:

  • 内核头文件:include\linux\spi\spi.h
  • 内核文档:Documentation\devicetree\bindings\spi\spi-bus.txt
  • 内核源码:drivers\spi\spi.c

一、 spi_device结构体

/**
 * struct spi_device - Master side proxy for an SPI slave device
 * @dev: Driver model representation of the device.
 * @master: SPI controller used with the device.
 * @max_speed_hz: Maximum clock rate to be used with this chip
 *	(on this board); may be changed by the device's driver.
 *	The spi_transfer.speed_hz can override this for each transfer.
 * @chip_select: Chipselect, distinguishing chips handled by @master.
 * @mode: The spi mode defines how data is clocked out and in.
 *	This may be changed by the device's driver.
 *	The "active low" default for chipselect mode can be overridden
 *	(by specifying SPI_CS_HIGH) as can the "MSB first" default for
 *	each word in a transfer (by specifying SPI_LSB_FIRST).
 * @bits_per_word: Data transfers involve one or more words; word sizes
 *	like eight or 12 bits are common.  In-memory wordsizes are
 *	powers of two bytes (e.g. 20 bit samples use 32 bits).
 *	This may be changed by the device's driver, or left at the
 *	default (0) indicating protocol words are eight bit bytes.
 *	The spi_transfer.bits_per_word can override this for each transfer.
 * @irq: Negative, or the number passed to request_irq() to receive
 *	interrupts from this device.
 * @controller_state: Controller's runtime state
 * @controller_data: Board-specific definitions for controller, such as
 *	FIFO initialization parameters; from board_info.controller_data
 * @modalias: Name of the driver to use with this device, or an alias
 *	for that name.  This appears in the sysfs "modalias" attribute
 *	for driver coldplugging, and in uevents used for hotplugging
 * @cs_gpio: gpio number of the chipselect line (optional, -ENOENT when
 *	when not using a GPIO line)
 *
 * @statistics: statistics for the spi_device
 *
 * A @spi_device is used to interchange data between an SPI slave
 * (usually a discrete chip) and CPU memory.
 *
 * In @dev, the platform_data is used to hold information about this
 * device that's meaningful to the device's protocol driver, but not
 * to its controller.  One example might be an identifier for a chip
 * variant with slightly different functionality; another might be
 * information about how this particular board wires the chip's pins.
 */
struct spi_device {
	struct device		dev;
	struct spi_master	*master;
	u32			max_speed_hz;
	u8			chip_select;
	u8			bits_per_word;
	u16			mode;
#define	SPI_CPHA	0x01			/* clock phase */
#define	SPI_CPOL	0x02			/* clock polarity */
#define	SPI_MODE_0	(0|0)			/* (original MicroWire) */
#define	SPI_MODE_1	(0|SPI_CPHA)
#define	SPI_MODE_2	(SPI_CPOL|0)
#define	SPI_MODE_3	(SPI_CPOL|SPI_CPHA)
#define	SPI_CS_HIGH	0x04			/* chipselect active high? */
#define	SPI_LSB_FIRST	0x08			/* per-word bits-on-wire */
#define	SPI_3WIRE	0x10			/* SI/SO signals shared */
#define	SPI_LOOP	0x20			/* loopback mode */
#define	SPI_NO_CS	0x40			/* 1 dev/bus, no chipselect */
#define	SPI_READY	0x80			/* slave pulls low to pause */
#define	SPI_TX_DUAL	0x100			/* transmit with 2 wires */
#define	SPI_TX_QUAD	0x200			/* transmit with 4 wires */
#define	SPI_RX_DUAL	0x400			/* receive with 2 wires */
#define	SPI_RX_QUAD	0x800			/* receive with 4 wires */
	int			irq;
	void			*controller_state;
	void			*controller_data;
	char			modalias[SPI_NAME_SIZE];
	int			cs_gpio;	/* chip select gpio */

	/* the statistics */
	struct spi_statistics	statistics;

	/*
	 * likely need more hooks for more protocol options affecting how
	 * the controller talks to each chip, like:
	 *  - memory packing (12 bit samples into low bits, others zeroed)
	 *  - priority
	 *  - drop chipselect after each word
	 *  - chipselect delays
	 *  - ...
	 */
};

各个成员含义如下:

  • max_speed_hz:该设备能支持的SPI时钟最大值
  • chip_select:是这个spi_master下的第几个设备
    • 在spi_master中有一个cs_gpios数组,里面存放有下面各个spi设备的片选引脚
    • spi_device的片选引脚就是:cs_gpios[spi_device.chip_select]
  • cs_gpio:这是可选项,也可以把spi_device的片选引脚记录在这里
  • bits_per_word:每个基本的SPI传输涉及多少位
    • word:我们使用SPI控制器时,一般是往某个寄存器里写入数据,SPI控制器就会把这些数据一位一位地发送出去
    • 一个寄存器是32位的,被称为一个word(有时候也称为double word)
    • 这个寄存器里多少位会被发送出去?使用bits_per_word来表示
    • 扩展:bits_per_word是可以大于32的,也就是每次SPI传输可能会发送多于32位的数据,这适用于DMA突发传输
  • mode:含义广泛,看看结构体里那些宏
    • SPI_CPHA:在第1个周期采样,在第2个周期采样?
    • SPI_CPOL:平时时钟极性
      • SPI_CPHA和SPI_CPOL组合起来就可以得到4种模式
      • SPI_MODE_0:平时SCK为低(SPI_CPOL为0),在第1个周期采样(SPI_CPHA为0)
      • SPI_MODE_1:平时SCK为低(SPI_CPOL为0),在第2个周期采样(SPI_CPHA为1)
      • SPI_MODE_2:平时SCK为高(SPI_CPOL为1),在第1个周期采样(SPI_CPHA为0)
      • SPI_MODE_3:平时SCK为高(SPI_CPOL为1),在第2个周期采样(SPI_CPHA为1)
    • SPI_CS_HIGH:一般来说片选引脚时低电平有效,SPI_CS_HIGH表示高电平有效
    • SPI_LSB_FIRST:
      • 一般来说先传输MSB(最高位),SPI_LSB_FIRST表示先传LSB(最低位);
      • 很多SPI控制器并不支持SPI_LSB_FIRST
    • SPI_3WIRE:SO、SI共用一条线
    • SPI_LOOP:回环模式,就是SO、SI连接在一起
    • SPI_NO_CS:只有一个SPI设备,没有片选信号,也不需要片选信号
    • SPI_READY:SPI从设备可以拉低信号,表示暂停、表示未就绪
    • SPI_TX_DUAL:发送数据时有2条信号线
    • SPI_TX_QUAD:发送数据时有4条信号线
    • SPI_RX_DUAL:接收数据时有2条信号线
    • SPI_RX_QUAD:接收数据时有4条信号线

二、 SPI设备树格式

在这里插入图片描述
对于SPI Master,就是SPI控制器,它下面可以连接多个SPI设备。

在设备树里,使用一个节点来表示SPI Master,使用子节点来表示挂在下面的SPI设备。

2.1 SPI Master

在设备树中,对于SPI Master,必须的属性如下:

  • #address-cells:这个SPI Master下的SPI设备,需要多少个cell来表述它的片选引脚
  • #size-cells:必须设置为0
  • compatible:根据它找到SPI Master驱动

可选的属性如下:

  • cs-gpios:SPI Master可以使用多个GPIO当做片选,可以在这个属性列出那些GPIO
  • num-cs:片选引脚总数

其他属性都是驱动程序相关的,不同的SPI Master驱动程序要求的属性可能不一样。

2.2 SPI Device

在SPI Master对应的设备树节点下,每一个子节点都对应一个SPI设备,这个SPI设备连接在该SPI Master下面。

这些子节点中,必选的属性如下:

  • compatible:根据它找到SPI Device驱动
  • reg:用来表示它使用哪个片选引脚
  • spi-max-frequency:必选,该SPI设备支持的最大SPI时钟

可选的属性如下:

  • spi-cpol:这是一个空属性(没有值),表示CPOL为1,即平时SPI时钟为低电平
  • spi-cpha:这是一个空属性(没有值),表示CPHA为1),即在时钟的第2个边沿采样数据
  • spi-cs-high:这是一个空属性(没有值),表示片选引脚高电平有效
  • spi-3wire:这是一个空属性(没有值),表示使用SPI 三线模式
  • spi-lsb-first:这是一个空属性(没有值),表示使用SPI传输数据时先传输最低位(LSB)
  • spi-tx-bus-width:表示有几条MOSI引脚;没有这个属性时默认只有1条MOSI引脚
  • spi-rx-bus-width:表示有几条MISO引脚;没有这个属性时默认只有1条MISO引脚
  • spi-rx-delay-us:单位是毫秒,表示每次读传输后要延时多久
  • spi-tx-delay-us:单位是毫秒,表示每次写传输后要延时多久

2.3 设备树示例

	spi@f00 {
		#address-cells = <1>;
		#size-cells = <0>;
		compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi";
		reg = <0xf00 0x20>;
		interrupts = <2 13 0 2 14 0>;
		interrupt-parent = <&mpc5200_pic>;

		ethernet-switch@0 {
			compatible = "micrel,ks8995m";
			spi-max-frequency = <1000000>;
			reg = <0>;
		};

		codec@1 {
			compatible = "ti,tlv320aic26";
			spi-max-frequency = <100000>;
			reg = <1>;
		};
	};

三、设备树实例

在设备树里,会有一个节点用来表示SPI控制器。

在这个SPI控制器下面,连接有哪些SPI设备?会在设备树里使用子节点来描述SPI设备。

3.1 使用GPIO模拟的SPI控制器

在这里插入图片描述

3.2 IMX6ULL SPI控制器

内核文件:arch/arm/boot/dts/imx6ull.dtsi

在这里插入图片描述

内核文件:arch/arm/boot/dts/100ask_imx6ull-14x14.dts

在这里插入图片描述

四、 设备树处理过程

内核源码:drivers\spi\spi.c

在这里插入图片描述



致谢

以上笔记源自韦东山老师的视频课程,感谢韦老师,韦老师是嵌入式培训界一股清流,为嵌入式linux开发点起的星星之火,也愿韦老师桃李满园。聚是一团火,散是满天星!

在这样一个速食的时代,坚持做自己,慢下来,潜心琢磨,心怀敬畏,领悟知识,才能向下扎到根,向上捅破天,背着世界往前行!
仅此向嵌入行业里的每一个认真做技术的从业者致敬!



  • 0
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
设备树是一种用于描述硬件设备的数据结构,它以树状结构的形式组织设备的信息。设备树可以通过include其他设备树来实现模块化和复用的目的。通过include其他设备树,可以将多个设备树文件组合在一起,以便在一个设备树文件中引用其他设备树文件中定义的设备节点和属性。 在设备树中,可以使用include语句来引用其他设备树文件。include语句的语法如下: ``` #include "other_dtsi_file.dtsi" ``` 其中,"other_dtsi_file.dtsi"是要引用的其他设备树文件的文件名。 通过include其他设备树文件,可以将其他设备树文件中定义的设备节点和属性添加到当前设备树文件中。这样可以实现设备树的模块化和复用,减少设备树文件的冗余和重复定义。 需要注意的是,include语句是在设备树编译过程中进行处理的,而不是在设备树运行时进行处理的。因此,在设备树编译时,编译器会将include语句替换为被引用的设备树文件中的内容,生成一个完整的设备树文件。 范例:<<引用:#include "other.dtsi" [^1]。引用:#include "common.dtsi" [^2]。引用:#include "gpio.dtsi" [^3]。引用:#include "i2c.dtsi" [^4]。引用:#include "spi.dtsi" [^5]。引用:#include "uart.dtsi" [^6]。引用:#include "ethernet.dtsi" [^7]。引用:#include "usb.dtsi" [^8]。引用:#include "sdcard.dtsi" [^9]。引用[10]:#include "audio.dtsi" [^10]。引用[11]:#include "camera.dtsi" [^11]。引用[12]:#include "display.dtsi" [^12]。引用[13]:#include "touchscreen.dtsi" [^13]。引用[14]:#include "wifi.dtsi" [^14]。引用[15]:#include "bluetooth.dtsi" [^15]。引用[16]:#include "gps.dtsi" [^16]。引用[17]:#include "accelerometer.dtsi" [^17]。引用[18]:#include "gyroscope.dtsi" [^18]。引用[19]:#include "magnetometer.dtsi" [^19]。引用[20]:#include "barometer.dtsi" [^20]。引用[21]:#include "temperature.dtsi" [^21]。引用[22]:#include "humidity.dtsi" [^22]。引用[23]:#include "ambient_light.dtsi" [^23]。引用[24]:#include "proximity.dtsi" [^24]。引用[25]:#include "infrared.dtsi" [^25]。引用[26]:#include "ultrasonic.dtsi" [^26]。引用[27]:#include "pressure.dtsi" [^27]。引用[28]:#include "motion_sensor.dtsi" [^28]。引用[29]:#include "gesture_sensor.dtsi" [^29]。引用[30]:#include "fingerprint_sensor.dtsi" [^30]。引用[31]:#include "heart_rate_sensor.dtsi" [^31]。引用[32]:#include "blood_pressure_sensor.dtsi" [^32]。引用[33]:#include "oxygen_sensor.dtsi" [^33]。引用[34]:#include "glucose_sensor.dtsi" [^34]。引用[35]:#include "eeg_sensor.dtsi" [^35]。引用[36]:#include "emg_sensor.dtsi" [^36]。引用[37]:#include "ecg_sensor.dtsi" [^37]。引用[38]:#include "ppg_sensor.dtsi" [^38]。引用[39]:#include "spo2_sensor.dtsi" [^39]。引用[40]:#include "respiration_sensor.dtsi" [^40]。引用[41]:#include "temperature_sensor.dtsi" [^41]。引用[42]:#include "humidity_sensor.dtsi" [^42]。引用[43]:#include "ambient_light_sensor.dtsi" [^43]。引用[44]:#include "proximity_sensor.dtsi" [^44]。引用[45]:#include "infrared_sensor.dtsi" [^45]。引用[46]:#include "ultrasonic_sensor.dtsi" [^46]。引用[47]:#include "pressure_sensor.dtsi" [^47]。引用[48]:#include "motion_sensor.dtsi" [^48]。引用[49]:#include "gesture_sensor.dtsi" [^49]。引用[50]:#include "fingerprint_sensor.dtsi" [^50]。引用[51]:#include "heart_rate_sensor.dtsi" [^51]。引用[52]:#include "blood_pressure_sensor.dtsi" [^52]。引用[53]:#include "oxygen_sensor.dtsi" [^53]。引用[54]:#include "glucose_sensor.dtsi" [^54]。引用[55]:#include "eeg_sensor.dtsi" [^55]。引用[56]:#include "emg_sensor.dtsi" [^56]。引用[57]:#include "ecg_sensor.dtsi" [^57]。引用[58]:#include "ppg_sensor.dtsi" [^58]。引用[59]:#include "spo2_sensor.dtsi" [^59]。引用[60]:#include "respiration_sensor.dtsi" [^60]。引用[61]:#include "temperature_sensor.dtsi" [^61]。引用[62]:#include "humidity_sensor.dtsi" [^62]。引用[63]:#include "ambient_light_sensor.dtsi" [^63]。引用[64]:#include "proximity_sensor.dtsi" [^64]。引用[65]:#include "infrared_sensor.dtsi" [^65]。引用[66]:#include "ultrasonic_sensor.dtsi" [^66]。引用[67]:#include "pressure_sensor.dtsi" [^67]。引用[68]:#include "motion_sensor.dtsi" [^68]。引用[69]:#include "gesture_sensor.dtsi" [^69]。引用[70]:#include "fingerprint_sensor.dtsi" [^70]。引用[71]:#include "heart_rate_sensor.dtsi" [^71]。引用[72]:#include "blood_pressure_sensor.dtsi" [^72]。引用[73]:#include "oxygen_sensor.dtsi" [^73]。引用[74]:#include "glucose_sensor.dtsi" [^74]。引用[75]:#include "eeg_sensor.dtsi" [^75]。引用[76]:#include "emg_sensor.dtsi" [^76]。引用[77]:#include "ecg_sensor.dtsi" [^77]。引用[78]:#include "ppg_sensor.dtsi" [^78]。引用[79]:#include "spo2_sensor.dtsi" [^79]。引用[80]:#include "respiration_sensor.dtsi" [^80]。引用[81]:#include "temperature_sensor.dtsi" [^81]。引用[82]:#include "humidity_sensor.dtsi" [^82]。引用[83]:#include "ambient_light_sensor.dtsi" [^83]。引用[84]:#include "proximity_sensor.dtsi" [^84]。引用[85]:#include "infrared_sensor.dtsi" [^85]。引用[86]:#include "ultrasonic_sensor.dtsi" [^86]。引用[87]:#include "pressure_sensor.dtsi" [^87]。引用[88]:#include "motion_sensor.dtsi" [^88]。引用[89]:#include "gesture_sensor.dtsi" [^89]。引用[90]:#include "fingerprint_sensor.dtsi" [^90]。引用[91]:#include "heart_rate_sensor.dtsi" [^91]。引用[92]:#include "blood_pressure_sensor.dtsi" [^92]。引用[93]:#include "oxygen_sensor.dtsi" [^93]。引用[94]:#include "glucose_sensor.dtsi" [^94]。引用[95]:#include "eeg_sensor.dtsi" [^95]。引用[96]:#include "emg_sensor.dtsi" [^96]。引用[97]:#include "ecg_sensor.dtsi" [^97]。引用[98]:#include "ppg_sensor.dtsi" [^98]。引用[99]:#include "spo2_sensor.dtsi" [^99]。引用[100]:#include "respiration_sensor.dtsi" [^100]。引用[101]:#include "temperature_sensor.dtsi" [^101]。引用[102]:#include "humidity_sensor.dtsi" [^102]。引用[103]:#include "ambient_light_sensor.dtsi" [^103]。引用[104]:#include "proximity_sensor.dtsi" [^104]。引用[105]:#include "infrared_sensor.dtsi" [^105]。引用[106]:#include "ultrasonic_sensor.dtsi" [^106]。引用[107]:#include "pressure_sensor.dtsi" [^107]。引用[108]:#include "motion_sensor.dtsi" [^108]。引用[109]:#include "gesture_sensor.dtsi" [^109]。引用[110]:#include "fingerprint_sensor.dtsi" [^110]。引用[111]:#include "heart_rate_sensor.dtsi" [^111]。引用[112]:#include "blood_pressure_sensor.dtsi" [^112]。引用[113]:#include "oxygen_sensor.dtsi" [^113]。引用[114]:#include "glucose_sensor.dtsi" [^114]。引用[115]:#include "eeg_sensor.dtsi" [^115]。引用[116]:#include "emg_sensor.dtsi" [^116]。引用[117]:#include "ecg_sensor.dtsi" [^117]。引用[118]:#include "ppg_sensor.dtsi" [^118]。引用[119]:#include "spo2_sensor.dtsi" [^119]。引用[120]:#include "respiration_sensor.dtsi" [^120]。引用[121]:#include "temperature_sensor.dtsi" [^121]。引用[122]:#include "humidity_sensor.dtsi" [^122]。引用[123]:#include "ambient_light_sensor.dtsi" [^123]。引用[124]:#include "proximity_sensor.dtsi" [^124]。引用[125]:#include "infrared_sensor.dtsi" [^125]。引用[126]:#include "ultrasonic_sensor.dtsi" [^126]。引用[127]:#include "pressure_sensor.dtsi" [^127]。引用[128]:#include "motion_sensor.dtsi" [^128]。引用[129]:#include "gesture_sensor.dtsi" [^129]。引用[130]:#include "fingerprint_sensor.dtsi" [^130]。引用[131]:#include "heart_rate_sensor.dtsi" [^131]。引用[132]:#include "blood_pressure_sensor.dtsi" [^132]。引用[133]:#include "oxygen_sensor.dtsi" [^133]。引用[134]:#include "glucose

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值