全志t3设备树与gpio使用

spi控制节点说明

spi设备在设备树里像描述i2c设备一样,需要在spi控制器节点里用子节点描述spi设备节点:
&spi0 { /* spi控制器节点 */
    ...
    cs-gpios = <&pio 2 3 GPIO_ACTIVE_HIGH>, <&pio 0 6 GPIO_ACTIVE_HIGH>;
        /* 片选的io口需与下面的spi设备节点一致  */

    spidev0 {
        compatible = "nanopi,spidev"; /* 此属性值用于与spi设备驱动匹配 */
        reg = <0>;  /*spi设备是没有设备地址的, 这里是指使用spi控制器的cs-gpios里的第几个片选io */
        status = "okay";  /* status属性值为"okay"表示spidev0设备使能, "disabled"表示设备没有使用*/
        spi-max-frequency = <10000000>; /* 指定spi设备的最大工作时钟 */

    ...
    buswidth = <8>; /* 传输以8位为单位 */
    mode = <0>;  /* 使用第几种工作时序(CPOL, CPHA) */
             /*但在现用的内核源码里发现, spi设备的工作时序并不是用mode属性值来指定的*/
             /* 如CPOL需要设1, 则只需在spi设备节点里加上"spi-cpol"属性即可; CPOL设0,则不写"spi-cpol"属性即可 */
             /* CPHA设1时, 则在设备节点里加上"spi-cpha"属性即可 */

    /*  还可以加入自定义的属性,用于指定工作时序方式及其它功能设置等 */
    }; 
};

SPI设备树配置

  1. 根据原理图修改对应引脚
    linux-3.10/arch/arm/boot/dts/sun8iw11p1-pinctrl.dtsi
    在这里插入图片描述
  2. 蔽掉引脚冲突功能
    linux-3.10/arch/arm/boot/dts/sun8iw11p1-pinctrl.dtsi
    sun8iw11p1-pinctrl.dtsi文件中,查找是否有其它功能使用PB13,PC19,PC20,PC21,PC22,如果有则蔽掉。
  3. spi2节点下增加对应设备属性
    在这里插入图片描述
  4. 设备查看
/sys/class/spi_master/spi2/spi2.1/modalias
/sys/bus/spi/devices/spi1.0/modalias

背光控制IO设备树配置

在这里插入图片描述

SPI控制引脚配置

在这里插入图片描述
** gpio所以计算 **
文件:
sunxi-gpio.h
GPIO定义:

#ifndef _DT_BINDINGS_GPIO_GPIO_H
#define _DT_BINDINGS_GPIO_GPIO_H

#define GPIO_ACTIVE_HIGH 0
#define GPIO_ACTIVE_LOW 1

#define  PA  0
#define  PB  1
#define  PC  2
#define  PD  3
#define  PE  4
#define  PF  5
#define  PG  6
#define  PH  7
#define  PI  8
#define  PJ  9
#define  PK  10
#define  PL  11
#define  PM  12
#define  PN  13
#define  PO  14
#define  PP  15
#define  default 0xffffffff
#endif

三、计算方式
举两个例子

1、PE8
gpio编号:4*32+8=136

2、PE9
gpio编号:4*32+9=137

链接: 全志GPIO使用

gpio控制器都是由厂商负责驱动好的,在设备树里关于gpio pinctrl的描述,如下:
在这里插入图片描述
其中“ #gpio-cells = <6>”表示在设备树里描述使用一个gpio口需要提供6个指定的参数。
通过文档,可以得知6个参数的分别作用如下:

 gpio = <&pio   1   1   1   1   1  0>;
    |      |    |   |   |   |   |  |-------------------表示有效电平
    |      |    |   |   |   |   |----------------------上下拉, 0关闭功能, 1上拉, 2下拉, 3保留
    |      |    |   |   |   |-------------------------驱动力,电流等级(0 - 3),级别越高,输出电流越大
    |      |    |   |   |----------------------------gpio功能类型,0输入, 1输出, 6和外部中断,7关闭功能(具体查手册)
    |      |    |   |------------------------------pin bank 内偏移(即组内第几个io口).
    |      |    |---------------------------------哪组gpio, PA(0),PB(1),PC(2),PD(3),PE(4),PF(5),PG(6),PH(7),PI(8),PJ(9),PK(10),PL(11)
    |      |--------------------------------------指向哪个gpio控制器,  pio / r_pio(PL组)
    |-----------------------------------------------------属性名字(随便命名)

获取设备树里设备节点的gpio口信息:
在这里插入图片描述
获取到int类型的gpio口后,就可以使用linux/gpio.h里的gpio口操作函数:
在这里插入图片描述
应用例子 :
dtsi:

example{
   compatible = "gpio,example";
   gpios = <&pio PE 8 1 1 1 1>; 
 };

代码:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
#include <linux/sys_config.h>
#include <linux/delay.h>

int example_probe(struct platform_device *pdev)
{
    struct device_node *nd = pdev->dev.of_node;
    int gpio;   
    struct gpio_config config;

    printk("gpio count:%d\n", of_gpio_named_count(nd, "gpios"));
    gpio = of_get_named_gpio_flags(nd, "gpios", 0, (enum of_gpio_flags *)&config);
    if (!gpio_is_valid(gpio))
        printk("gpio isn't valid\n");
    if (gpio_request(gpio, pdev->name) < 0)
            printk("gpio request failed %d\n", gpio);

    gpio_direction_output(gpio, 1);
    msleep(3000);
    gpio_direction_output(gpio, 0);
    msleep(3000);
    gpio_direction_input(gpio);
    gpio_free(gpio);
    return 0;
}

int example_remove(struct platform_device *pdev)
{
    printk("in myremove ...\n");
    return 0;
}

struct of_device_id ids[] = {
    {.compatible = "gpio,example"},
    {},
};

struct platform_driver mydrv = {
    .probe = example_probe,
    .remove = example_remove,

    .driver = {
        .owner = THIS_MODULE,
        .name = "example" ,

        .of_match_table = ids,
    },
};

module_platform_driver(example);
MODULE_LICENSE("GPL");
### 全志 T527 SPI 配置使用教程 对于全志T527开发板上的SPI配置,可以参照类似的全志系列处理器的设置流程。具体来说,在进行SPI设备初始化前,需先确保内核选项已正确开启支持。 #### 1. 内核配置 进入Kernel Setup菜单,依次选择Drivers Setup -> SoC HAL Drivers -> SPI Devices,确认对应项已被激活[^3]。 #### 2. 设备树节点定义 编辑设备树源文件(DTS),添加或修改有关PN512模块或其他SPI外设的相关条目。通常情况下,这涉及指定SPI控制器以及其子节点下的参数,如模式、频率等属性: ```dts spi0: spi@... { compatible = "allwinner,sun50i-a64-spi"; reg = <...>; interrupts = <...>; status = "okay"; pn512@0 { compatible = "nxp,pn512"; reg = <0>; spi-max-frequency = <1000000>; /* 设置最大时钟频率 */ pinctrl-names = "default"; pinctrl-0 = <&pn512_pins_a>; // 更多特定于PN512的配置... }; }; ``` 上述DTS片段展示了如何为PN512 NFC读卡器创建一个子节点,并指定了必要的物理层特性[^1]。 #### 3. 用户空间编程接口 一旦完成了底层硬件抽象层(HAL)和设备树中的适当调整之后,应用程序开发者就可以利用标准Linux API来进行数据传输操作了。下面给出一段简单的Python代码示例,用于发送命令并接收响应: ```python import spidev import time # 打开SPI总线 spi_bus = 0 spi_device = 0 spi = spidev.SpiDev() spi.open(spi_bus, spi_device) try: # 设置通信速率 spi.max_speed_hz = 1000000 while True: message_to_send = [0x00, ... ] # 替换成实际要发送的数据包 response = spi.xfer(message_to_send) print(f"Received data from device: {response}") time.sleep(1) finally: spi.close() ``` 这段脚本实现了基本的SPI交互逻辑,其中`spidev`库提供了访问Linux下SPI设备的能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值