fangkaixin 发表于 2024-1-1 15:34

【STM32MP135F-DK】硬件资源测试:玩转GPIO

本帖最后由 fangkaixin 于 2024-1-1 15:50 编辑

<div>前面介绍了如何通过简单的配置,对Linux设备树进行修改,实现在用户空间通过sysfs来控制LED灯亮灭,大家对STM32MP135F-DK的引脚控制应该有了简单的认识,接下来就详细介绍下Linux中控制GPIO的方法。</div>

<div>实际Linux上控制GPIO的方式是非常多样化的,可以满足不同类型用户的需求,今天带大家一起基于STM32MP135F-DK套件的Linux系统来玩转GPIO,还是以LED为例,主要通过另外两个方面来进行测试验证:</div>

<div>一是在系统内核空间,通过修改内核驱动来控制LED;</div>

<div>二是在用户空间,用C代码通过mmap直接对LED进行控制</div>

<div>&nbsp;</div>

<div>
<hr />
<p>&nbsp;</p>
</div>

<h2>概念介绍</h2>

<div>每个ST微控制器管脚都经过多路复用,以支持多种功能。可以配置为以下在三种模式:</div>

<ul>
        <li>通用输入/输出GPIO:由软件控制</li>
        <li>模拟GPIO:由硬件模块直接控制</li>
        <li>Alternate功能:由硬件模块直接控制</li>
</ul>

<div>可以使用两种框架来配置和控制给定的引脚:<strong>pinctrl</strong>&nbsp;和&nbsp;<strong>GPIOLib</strong>。</div>

<ul>
        <li><strong>Pinctrl</strong>&nbsp;主要用于引脚由内部外设控制的情况。Pinctrl 处理引脚配置,并允许将特定功能分配给引脚。</li>
        <li><strong>GPIOLib</strong>&nbsp;用于需要在运行时动态控制引脚的情况。GPIOLib 用于通过软件控制引脚。</li>
</ul>

<div>此外,当引脚用作外部中断源时,Irqchip框架提供了一个允许配置此中断的&nbsp;API。</div>

<div>引脚管理框架</div>

<div></div>

<hr />
<h2>通过内核驱动控制LED</h2>

<div>目标:使用ST的gpiolib框架,在内核层实现对LED(GPIO-PA13)的控制</div>

<div>步骤:</div>

<ul>
        <li><em><strong>修改设备树,添加对应的GPIO设备文件描述,并重新编译设备树文件</strong></em></li>
</ul>

<p><em>make ARCH=arm </em><em>dtbs</em><em> LOADADDR=0xC2000040</em></p>

<div></div>

<div></div>

<div></div>

<ul>
        <li><em><strong>编写内核模块代码,Makefile文件,并编译</strong></em></li>
</ul>

<p><em>make</em></p>

<p><em>make install</em></p>

<div></div>

<div></div>

<div></div>

<ul>
        <li><em><strong>更新设备树和设备模块到开发板</strong></em></li>
</ul>

<p><em>scp</em><em> arch/arm/boot/</em><em>dts</em><em>/stm32mp135*.</em><em>dtb</em> <a href="mailto:root@%3cyour.ip.address.x%3e:/boot"><em>root@&lt;your.ip.address.x&gt;:/boot</em></a></p>

<p><em>scp</em><em> outputs/lib/modules/6.1.28/extra/</em><em>red_</em><em>led.ko</em> <a href="mailto:root@%3cyour.ip.address.x%3e:/lib/modules">root@&lt;your.ip.address.x&gt;:/lib/modules</a><em>/</em><em>6.1.28</em> <em>red_led.ko</em></p>

<div></div>

<div></div>

<ul>
        <li><em><strong>更新内核模块依赖,同步内存后重启</strong></em></li>
</ul>

<p></p>

<ul>
        <li><em><strong>加载内核模块验证</strong></em></li>
</ul>

<p>检查当前gpio状态(以防有gpio冲突)</p>

<div></div>

<p><em>modprobe</em> <em>red_led</em></p>

<p>效果:led快速闪烁<br />
</p>

<ul>
        <li>退出</li>
</ul>

<p><em>rmmod</em> <em>red_led</em></p>

<div></div>

<hr />
<h2>在用户空间编写C代码通过mmap方法直接控制LED</h2>

<div>在用户空间中控制LED,前面介绍了sysfs操作的方法,这里介绍另一种方式:mmap。mmap可以将物理设备/dev/mem映射到内存,通过读写内存的方式操作GPIO寄存器,由于避免了系统调用,不需要用户空间和内核空间频繁切换,可以提高使用效率。</div>

<div>还是以上面的红色LED:GPIO-PA13为例</div>

<div>我们先查找一下手册中该GPIO的内存地址:参考手册下载地址<a href="https://www.st.com/resource/en/reference_manual/DM00670465-.pdf">STM32MP13xx advanced Arm&lt;Sup&gt;&reg;&lt;/Sup&gt;-based 32-bit MPUs - Reference manual</a></div>

<div></div>

<div></div>

<div>可以看到GPIOA的内存起始地址是<span style="color:#3498db;">0x50002000 ~ 0x500023FF</span></div>

<div>接着找到相关寄存器,进行配置,以下是寄存器地址</div>

<div><span style="font-size:18px;"><em><strong>配置相关寄存器</strong></em></span></div>

<div></div>

<div></div>

<div><strong><em>1)MODER寄存器用来配置GPIO的模式,这里我们需要配置为输出0x01</em></strong></div>

<div></div>

<div>从图中可以看出PA13对应的MODER13是对应寄存器的bit27和bit26,可以编写配置代码如下</div>

<div></div>

<div><strong><em>2)OTYPER寄存器,配置为推挽输出状态,0x00</em></strong></div>

<div></div>

<div></div>

<div><em><strong>3)BSRR寄存器用来</strong>改变管脚状态高电平还是低电平,这是一个只写寄存器,<strong>对寄存器高</strong><strong> 16bit </strong><strong>写</strong><strong>1 </strong><strong>对应管脚为</strong><strong>低</strong><strong>电平,对寄存器低</strong><strong>16bit</strong><strong>写</strong><strong>1</strong><strong>对应管脚为</strong><strong>高</strong><strong>电平。写</strong><strong> 0 ,</strong><strong>无动作</strong></em></div>

<div>用来控制电平的翻转,实现LED的闪烁效果</div>

<div></div>

<div></div>

<div>
<hr /><span style="font-size:18px;"><strong>效果展示:</strong></span></div>

<div>e96e59d4ce1819159a16831533495346<br />
本文中涉及到的代码:</div>

<div>
<pre>
<code class="language-cpp">/*led内核模块*/
#include &lt;linux/module.h&gt;
#include &lt;linux/of_device.h&gt;
#include &lt;linux/kernel.h&gt;
#include &lt;linux/delay.h&gt;
#include &lt;linux/gpio/consumer.h&gt;
#include &lt;linux/platform_device.h&gt;
#include &lt;linux/init.h&gt;
#include &lt;linux/sched.h&gt;
#include &lt;linux/time.h&gt;
#include &lt;linux/timer.h&gt;

struct gpio_desc *red;

struct timer_list timer;

static void led_expires(struct timer_list *t)
{
    int toggle;
    if(t == &amp;timer){
      printk("red led toggled\n");
      toggle = gpiod_get_value(red);
      gpiod_set_value(red, !toggle);
      mod_timer(t, jiffies + HZ/50);
    }
}
static int gpio_init_probe(struct platform_device *pdev)
{
   printk("Start example gpio red blink\n");

   red = devm_gpiod_get(&amp;pdev-&gt;dev, "redled", GPIOD_OUT_LOW);

   timer_setup(&amp;timer, led_expires, 0);
   mod_timer(&amp;timer, jiffies + HZ/50);

   printk("start timer\n");

   return(0);
}

static int gpio_exit_remove(struct platform_device *pdev)
{
   printk("Example gpio red blink exit\n");
   
   del_timer(&amp;timer);
   
   return(0);
}


static struct of_device_id foo_match[] = {
    {.compatible = "gpio-redled"},
    {}
};

static struct platform_driver foo_driver = {
    .probe = gpio_init_probe,
    .remove = gpio_exit_remove,
    .driver = {
      .name = "foo_driver",
                .owner = THIS_MODULE,
                .of_match_table = foo_match,
    }
};

module_platform_driver(foo_driver);

MODULE_AUTHOR("Frank");
MODULE_DESCRIPTION("Gpio red flash");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:foo_driver");</code></pre>

<pre>
<code class="language-cpp"># Makefile for external out-of-tree Linux kernel module
/*内核模块对应的Makefile*/
# Object file(s) to be built
obj-m := red_led.o

# Path to the directory that contains the Linux kernel source code
# and the configuration file (.config)
KERNEL_DIR ?= /home/frank/STM32MP135F-DK/source/stm32mp1-openstlinux-6.1-yocto-mickledore-mp1-v23.06.21/sources/arm-ostl-linux-gnueabi/linux-stm32mp-6.1.28-stm32mp-r1-r0/linux-6.1.28

# Path to the directory that contains the generated objects
DESTDIR ?= /home/frank/STM32MP135F-DK/demo/test_leds/outputs

# Path to the directory that contains the source file(s) to compile
PWD := $(shell pwd)

default:
        $(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules

install:
        $(MAKE) -C $(KERNEL_DIR) M=$(PWD) INSTALL_MOD_PATH=$(DESTDIR) modules_install

clean:
        $(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean</code></pre>

<pre>
<code class="language-cpp">/*led应用程序*/
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;errno.h&gt;
#include &lt;fcntl.h&gt;
#include &lt;sys/mman.h&gt;
#include &lt;string.h&gt;
#include &lt;stdint.h&gt;
#include &lt;unistd.h&gt;
#include &lt;signal.h&gt;

#define MEM_DEV               "/dev/mem"
#define GPIOA_START_ADDR      0x50002000
#define GPIOA_END_ADDR          0x500023FF
#define GPIOA_MAP_SIZE          (GPIOA_END_ADDR - GPIOA_START_ADDR)

#define GPIO_REG_MODER 0x00   /**&lt; GPIO port mode register */
#define GPIO_REG_OTYPER 0x04    /**&lt; GPIO port output type register */
#define GPIO_REG_BSRR 0x18      /**&lt; GPIO port bit set/reset register */

#define GPIO_PIN_13                  ((uint16_t)0x2000U)

#define GPIO_PIN_OUTPUT_DIRECTION   0x01 /**&lt; Output */
#define GPIO_PIN_OUTPUT_PUSHPULL      0x00 /**&lt; Output Push Pull Mode */
#define GPIO_PIN_13_REG_DEFINITION   (GPIOA_START_ADDR+GPIO_PIN_13)
int main(int argc, char **argv)
{
int ret = EXIT_SUCCESS;
static void *mmapBase = NULL; /* Virtual base address */


/* Try to open the mem device special file */
int fdMem = open(MEM_DEV, O_RDWR | O_SYNC);
if (fdMem &lt; 1)
{
    exit(1);
}

/* Map memory region for the gpio registers */
mmapBase = mmap(NULL,
          GPIOA_MAP_SIZE,
          PROT_READ | PROT_WRITE,
          MAP_SHARED,
          fdMem,
          GPIOA_START_ADDR);
if (mmapBase == (void*) -1)
{
    exit(1);
}

{ /* MODER */
    /* Load the different gpio register pointers with its address */
    volatile uint32_t *gpioRegAddr = mmapBase + GPIO_REG_MODER;
    /* Get the value of the gpio direction register */
    uint32_t gpioRegVal = *gpioRegAddr;
    /* Clear the GPIO, write it back to the direction register */   
    gpioRegVal &amp;= ~(0x03 &lt;&lt; (13 * 2)); /* mask out the 2 bits giving the direction */
    gpioRegVal |= ((GPIO_PIN_OUTPUT_DIRECTION) &lt;&lt; (13 * 2));
    *gpioRegAddr = gpioRegVal;
}

{ /* OTYPE */
    /* Load the different gpio register pointers with its address */
    volatile uint32_t *gpioRegAddr = mmapBase + GPIO_REG_OTYPER;
    /* Get the value of the gpio direction register */
    uint32_t gpioRegVal = *gpioRegAddr;
    /* Clear the GPIO, write it back to the direction register */   
    gpioRegVal &amp;= ~(0x0 &lt;&lt; (13)); /* mask out */
    gpioRegVal |= ((GPIO_PIN_OUTPUT_PUSHPULL) &lt;&lt; (13));
    *gpioRegAddr = gpioRegVal;
}
      
volatile uint32_t *const gpioSetClearDataOutAddr = mmapBase + GPIO_REG_BSRR;

while(1)
{
    *gpioSetClearDataOutAddr = GPIO_PIN_13; /* set the pin */
    usleep(50*1000);
    *gpioSetClearDataOutAddr = (uint32_t)(GPIO_PIN_13 &lt;&lt; 16); /* reset the pin */
    usleep(50*1000);
}
return ret;
}</code></pre>

<pre>
<code class="language-cpp">/*应用程序对应的Makefile*/
PROG = led
SRCS = led.c

CLEANFILES = $(PROG)

# Add / change option in CFLAGS and LDFLAGS
CFLAGS += -Wall
LDFLAGS +=

all: $(PROG)

$(PROG): $(SRCS)
        $(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)

clean:
        rm -f $(CLEANFILES) $(patsubst %.c,%.o, $(SRCS))</code></pre>

<pre>
<code class="language-cpp">//设备树
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
* Copyright (C) STMicroelectronics 2021 - All Rights Reserved
* Author: Alexandre Torgue &lt;alexandre.torgue@foss.st.com&gt; for STMicroelectronics.
*/

/dts-v1/;

#include &lt;dt-bindings/gpio/gpio.h&gt;
#include &lt;dt-bindings/input/input.h&gt;
#include &lt;dt-bindings/leds/common.h&gt;
#include &lt;dt-bindings/regulator/st,stm32mp13-regulator.h&gt;
#include &lt;dt-bindings/rtc/rtc-stm32.h&gt;
#include "stm32mp135.dtsi"
#include "stm32mp13xf.dtsi"
#include "stm32mp13-pinctrl.dtsi"

/ {
        model = "STMicroelectronics STM32MP135F-DK Discovery Board";
        compatible = "st,stm32mp135f-dk", "st,stm32mp135";

        aliases {
                ethernet0 = &amp;eth1;
                ethernet1 = &amp;eth2;
                serial0 = &amp;uart4;
                serial1 = &amp;usart1;
                serial2 = &amp;uart8;
                serial3 = &amp;usart2;
        };

        chosen {
                stdout-path = "serial0:115200n8";
                #address-cells = &lt;1&gt;;
                #size-cells = &lt;1&gt;;
                ranges;

                framebuffer {
                        compatible = "simple-framebuffer";
                        clocks = &lt;&amp;rcc LTDC_PX&gt;;
                        status = "disabled";
                };
        };

        clocks {
                clk_ext_camera: clk-ext-camera {
                        #clock-cells = &lt;0&gt;;
                        compatible = "fixed-clock";
                        clock-frequency = &lt;24000000&gt;;
                };

                clk_mco1: clk-mco1 {
                        #clock-cells = &lt;0&gt;;
                        compatible = "fixed-clock";
                        clock-frequency = &lt;24000000&gt;;
                };
        };

        memory@c0000000 {
                device_type = "memory";
                reg = &lt;0xc0000000 0x20000000&gt;;
        };

        reserved-memory {
                #address-cells = &lt;1&gt;;
                #size-cells = &lt;1&gt;;
                ranges;

                optee@dd000000 {
                        reg = &lt;0xdd000000 0x3000000&gt;;
                        no-map;
                };
        };

        gpio-keys {
                compatible = "gpio-keys";

                // user-pa13 {
                //         label = "User-PA13";
                //         linux,code = &lt;BTN_1&gt;;
                //         gpios = &lt;&amp;gpioa 13 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)&gt;;
                // };
        };

        leds {
                compatible = "gpio-leds";

                led-blue {
                        function = LED_FUNCTION_HEARTBEAT;
                        color = &lt;LED_COLOR_ID_BLUE&gt;;
                        gpios = &lt;&amp;gpioa 14 GPIO_ACTIVE_LOW&gt;;
                        linux,default-trigger = "heartbeat";
                        default-state = "off";
                };

                // led-red {
                //         function = LED_FUNCTION_ACTIVITY;
                //         color = &lt;LED_COLOR_ID_RED&gt;;
                //         gpios = &lt;&amp;gpioa 13 GPIO_ACTIVE_LOW&gt;;
                //         linux,default-trigger = "active";
                //         default-state = "off";
                // };
        };

        foo_device {
                compatible = "gpio-redled";
                status = "okay";
                redled-gpios = &lt;&amp;gpioa 13 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)&gt;;
        };

        panel_backlight: panel-backlight {
                compatible = "gpio-backlight";
                gpios = &lt;&amp;gpioe 12 GPIO_ACTIVE_HIGH&gt;;
                default-on;
                default-brightness-level = &lt;0&gt;;
                status = "okay";
        };

        panel_rgb: panel-rgb {
                compatible = "rocktech,rk043fn48h", "panel-dpi";
                enable-gpios = &lt;&amp;gpioi 7 GPIO_ACTIVE_HIGH&gt;;
                backlight = &lt;&amp;panel_backlight&gt;;
                power-supply = &lt;&amp;scmi_v3v3_sw&gt;;
                data-mapping = "bgr666";
                status = "okay";

                width-mm = &lt;105&gt;;
                height-mm = &lt;67&gt;;

                port {
                        panel_in_rgb: endpoint {
                                remote-endpoint = &lt;&amp;ltdc_out_rgb&gt;;
                        };
                };

                panel-timing {
                        clock-frequency = &lt;10000000&gt;;
                        hactive = &lt;480&gt;;
                        vactive = &lt;272&gt;;
                        hsync-len = &lt;52&gt;;
                        hfront-porch = &lt;10&gt;;
                        hback-porch = &lt;10&gt;;
                        vsync-len = &lt;10&gt;;
                        vfront-porch = &lt;10&gt;;
                        vback-porch = &lt;10&gt;;
                        hsync-active = &lt;0&gt;;
                        vsync-active = &lt;0&gt;;
                        de-active = &lt;1&gt;;
                        pixelclk-active = &lt;1&gt;;
                };
        };

        v3v3_ao: v3v3-ao {
                compatible = "regulator-fixed";
                regulator-name = "v3v3_ao";
                regulator-min-microvolt = &lt;3300000&gt;;
                regulator-max-microvolt = &lt;3300000&gt;;
                regulator-always-on;
        };

        wake_up {
                compatible = "gpio-keys";
                status = "okay";

                button {
                        label = "wake-up";
                        linux,code = &lt;KEY_WAKEUP&gt;;
                        interrupts-extended = &lt;&amp;optee 0&gt;;
                        status = "okay";
                };
        };

        wifi_pwrseq: wifi-pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = &lt;&amp;mcp23017 11 GPIO_ACTIVE_LOW&gt;;
        };
};

&amp;adc_1 {
        pinctrl-names = "default";
        pinctrl-0 = &lt;&amp;adc1_usb_cc_pins_a&gt;;
        vdda-supply = &lt;&amp;scmi_vdd_adc&gt;;
        vref-supply = &lt;&amp;scmi_vdd_adc&gt;;
        status = "okay";
        adc1: adc@0 {
                status = "okay";
                /*
               * Type-C USB_PWR_CC1 &amp; USB_PWR_CC2 on in6 &amp; in12.
               * Use at least 5 * RC time, e.g. 5 * (Rp + Rd) * C:
               * 5 * (5.1 + 47kOhms) * 5pF =&gt; 1.3us.
               * Use arbitrary margin here (e.g. 5us).
               */
                channel@6 {
                        reg = &lt;6&gt;;
                        st,min-sample-time-ns = &lt;5000&gt;;
                };
                channel@12 {
                        reg = &lt;12&gt;;
                        st,min-sample-time-ns = &lt;5000&gt;;
                };
        };
};

&amp;arm_wdt {
        timeout-sec = &lt;32&gt;;
        status = "okay";
};

&amp;crc1 {
        status = "okay";
};

&amp;cryp {
        status = "okay";
};

&amp;dcmipp {
        status = "okay";
        pinctrl-names = "default", "sleep";
        pinctrl-0 = &lt;&amp;dcmipp_pins_a&gt;;
        pinctrl-1 = &lt;&amp;dcmipp_sleep_pins_a&gt;;
        port {
                dcmipp_0: endpoint {
                        remote-endpoint = &lt;&amp;mipid02_2&gt;;
                        bus-width = &lt;8&gt;;
                        hsync-active = &lt;0&gt;;
                        vsync-active = &lt;0&gt;;
                        pclk-sample = &lt;0&gt;;
                        pclk-max-frequency = &lt;120000000&gt;;
                };
        };
};

&amp;dts {
        status = "okay";
};

&amp;eth1 {
        status = "okay";
        pinctrl-0 = &lt;&amp;eth1_rmii_pins_a&gt;;
        pinctrl-1 = &lt;&amp;eth1_rmii_sleep_pins_a&gt;;
        pinctrl-names = "default", "sleep";
        phy-mode = "rmii";
        max-speed = &lt;100&gt;;
        phy-handle = &lt;&amp;phy0_eth1&gt;;
        nvmem-cells = &lt;&amp;ethernet_mac1_address&gt;;
        nvmem-cell-names = "mac-address";

        mdio1 {
                #address-cells = &lt;1&gt;;
                #size-cells = &lt;0&gt;;
                compatible = "snps,dwmac-mdio";

                phy0_eth1: ethernet-phy@0 {
                        compatible = "ethernet-phy-id0007.c131";
                        reset-gpios =&lt;&amp;mcp23017 9 GPIO_ACTIVE_LOW&gt;;
                        reg = &lt;0&gt;;
                        wakeup-source;
                };
        };
};

&amp;eth2 {
        status = "okay";
        pinctrl-0 = &lt;&amp;eth2_rmii_pins_a&gt;;
        pinctrl-1 = &lt;&amp;eth2_rmii_sleep_pins_a&gt;;
        pinctrl-names = "default", "sleep";
        phy-mode = "rmii";
        max-speed = &lt;100&gt;;
        phy-handle = &lt;&amp;phy0_eth2&gt;;
        st,ext-phyclk;
        phy-supply = &lt;&amp;scmi_v3v3_sw&gt;;
        nvmem-cells = &lt;&amp;ethernet_mac2_address&gt;;
        nvmem-cell-names = "mac-address";

        mdio1 {
                #address-cells = &lt;1&gt;;
                #size-cells = &lt;0&gt;;
                compatible = "snps,dwmac-mdio";
                phy0_eth2: ethernet-phy@0 {
                        compatible = "ethernet-phy-id0007.c131";
                        reset-gpios = &lt;&amp;mcp23017 10 GPIO_ACTIVE_LOW&gt;;
                        reg = &lt;0&gt;;
                };
        };
};

&amp;i2c1 {
        pinctrl-names = "default", "sleep";
        pinctrl-0 = &lt;&amp;i2c1_pins_a&gt;;
        pinctrl-1 = &lt;&amp;i2c1_sleep_pins_a&gt;;
        i2c-scl-rising-time-ns = &lt;96&gt;;
        i2c-scl-falling-time-ns = &lt;3&gt;;
        clock-frequency = &lt;1000000&gt;;
        status = "okay";
        /* spare dmas for other usage */
        /delete-property/dmas;
        /delete-property/dma-names;

        mcp23017: pinctrl@21 {
                compatible = "microchip,mcp23017";
                reg = &lt;0x21&gt;;
                gpio-controller;
                #gpio-cells = &lt;2&gt;;
                interrupts = &lt;12 IRQ_TYPE_LEVEL_LOW&gt;;
                interrupt-parent = &lt;&amp;gpiog&gt;;
                pinctrl-names = "default";
                pinctrl-0 = &lt;&amp;mcp23017_pins_a&gt;;
                interrupt-controller;
                #interrupt-cells = &lt;2&gt;;
                microchip,irq-mirror;
        };

        typec@53 {
                compatible = "st,stm32g0-typec";
                reg = &lt;0x53&gt;;
                /* Alert pin on PI2 (PWR wakeup pin), managed by optee */
                interrupts-extended = &lt;&amp;optee 1&gt;;
                firmware-name = "stm32g0-ucsi.mp135f-dk.fw";
                wakeup-source;
                connector {
                        compatible = "usb-c-connector";
                        label = "USB-C";

                        port {
                                con_usb_c_g0_ep: endpoint {
                                        remote-endpoint = &lt;&amp;usbotg_hs_ep&gt;;
                                };
                        };
                };
        };
};

&amp;i2c5 {
        pinctrl-names = "default", "sleep";
        pinctrl-0 = &lt;&amp;i2c5_pins_a&gt;;
        pinctrl-1 = &lt;&amp;i2c5_sleep_pins_a&gt;;
        i2c-scl-rising-time-ns = &lt;170&gt;;
        i2c-scl-falling-time-ns = &lt;5&gt;;
        clock-frequency = &lt;400000&gt;;
        status = "okay";
        /* spare dmas for other usage */
        /delete-property/dmas;
        /delete-property/dma-names;

        stmipi: stmipi@14 {
                compatible = "st,st-mipid02";
                reg = &lt;0x14&gt;;
                status = "okay";
                clocks = &lt;&amp;clk_mco1&gt;;
                clock-names = "xclk";
                VDDE-supply = &lt;&amp;scmi_v1v8_periph&gt;;
                VDDIN-supply = &lt;&amp;scmi_v1v8_periph&gt;;
                reset-gpios = &lt;&amp;mcp23017 2 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)&gt;;

                ports {
                        #address-cells = &lt;1&gt;;
                        #size-cells = &lt;0&gt;;
                        port@0 {
                                reg = &lt;0&gt;;

                                mipid02_0: endpoint {
                                        data-lanes = &lt;1 2&gt;;
                                        lane-polarities = &lt;0 0 0&gt;;
                                        remote-endpoint = &lt;&amp;gc2145_ep&gt;;
                                };
                        };
                        port@2 {
                                reg = &lt;2&gt;;

                                mipid02_2: endpoint {
                                        bus-width = &lt;8&gt;;
                                        hsync-active = &lt;0&gt;;
                                        vsync-active = &lt;0&gt;;
                                        pclk-sample = &lt;0&gt;;
                                        remote-endpoint = &lt;&amp;dcmipp_0&gt;;
                                };
                        };
                };
        };

        gc2145: gc2145@3c {
                compatible = "galaxycore,gc2145";
                reg = &lt;0x3c&gt;;
                clocks = &lt;&amp;clk_ext_camera&gt;;
                IOVDD-supply = &lt;&amp;scmi_v3v3_sw&gt;;
                AVDD-supply = &lt;&amp;scmi_v3v3_sw&gt;;
                DVDD-supply = &lt;&amp;scmi_v3v3_sw&gt;;
                powerdown-gpios = &lt;&amp;mcp23017 3 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)&gt;;
                reset-gpios = &lt;&amp;mcp23017 4 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)&gt;;
                status = "okay";

                port {
                        gc2145_ep: endpoint {
                                remote-endpoint = &lt;&amp;mipid02_0&gt;;
                                clock-lanes = &lt;0&gt;;
                                data-lanes = &lt;1 2&gt;;
                        };
                };
        };

        ov5640: camera@3c {
                compatible = "ovti,ov5640";
                reg = &lt;0x3c&gt;;
                clocks = &lt;&amp;clk_ext_camera&gt;;
                clock-names = "xclk";
                DOVDD-supply = &lt;&amp;scmi_v3v3_sw&gt;;
                status = "disabled";
                powerdown-gpios = &lt;&amp;mcp23017 3 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)&gt;;
                reset-gpios = &lt;&amp;mcp23017 4 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)&gt;;

                port {
                        ov5640_0: endpoint {
                                /*remote-endpoint = &lt;&amp;mipid02_0&gt;;*/
                                clock-lanes = &lt;0&gt;;
                                data-lanes = &lt;1 2&gt;;
                        };
                };
        };

        goodix: goodix-ts@5d {
                compatible = "goodix,gt911";
                reg = &lt;0x5d&gt;;
                pinctrl-names = "default";
                pinctrl-0 = &lt;&amp;goodix_pins_a&gt;;
                interrupt-parent = &lt;&amp;gpiof&gt;;
                interrupts = &lt;5 IRQ_TYPE_EDGE_FALLING&gt;;
                reset-gpios = &lt;&amp;gpioh 2 GPIO_ACTIVE_LOW&gt;;
                AVDD28-supply = &lt;&amp;scmi_v3v3_sw&gt;;
                VDDIO-supply = &lt;&amp;scmi_v3v3_sw&gt;;
                touchscreen-size-x = &lt;480&gt;;
                touchscreen-size-y = &lt;272&gt;;
                status = "okay" ;
        };
};

&amp;ltdc {
        pinctrl-names = "default", "sleep";
        pinctrl-0 = &lt;&amp;ltdc_pins_a&gt;;
        pinctrl-1 = &lt;&amp;ltdc_sleep_pins_a&gt;;
        status = "okay";

        port {
                ltdc_out_rgb: endpoint {
                        remote-endpoint = &lt;&amp;panel_in_rgb&gt;;
                };
        };
};

&amp;rtc {
        st,lsco = &lt;RTC_OUT2_RMP&gt;;
        pinctrl-0 = &lt;&amp;rtc_out2_rmp_pins_a&gt;;
        pinctrl-names = "default";
        status = "okay";
};

&amp;scmi_regu {
        scmi_vddcpu: voltd-vddcpu {
                reg = &lt;VOLTD_SCMI_STPMIC1_BUCK1&gt;;
                regulator-name = "vddcpu";
        };
        scmi_vdd: voltd-vdd {
                reg = &lt;VOLTD_SCMI_STPMIC1_BUCK3&gt;;
                regulator-name = "vdd";
        };
        scmi_vddcore: voltd-vddcore {
                reg = &lt;VOLTD_SCMI_STPMIC1_BUCK4&gt;;
                regulator-name = "vddcore";
        };
        scmi_vdd_adc: voltd-vdd-adc {
                reg = &lt;VOLTD_SCMI_STPMIC1_LDO1&gt;;
                regulator-name = "vdd_adc";
        };
        scmi_vdd_usb: voltd-vdd-usb {
                reg = &lt;VOLTD_SCMI_STPMIC1_LDO4&gt;;
                regulator-name = "vdd_usb";
        };
        scmi_vdd_sd: voltd-vdd-sd {
                reg = &lt;VOLTD_SCMI_STPMIC1_LDO5&gt;;
                regulator-name = "vdd_sd";
        };
        scmi_v1v8_periph: voltd-v1v8-periph {
                reg = &lt;VOLTD_SCMI_STPMIC1_LDO6&gt;;
                regulator-name = "v1v8_periph";
        };
        scmi_v3v3_sw: voltd-v3v3-sw {
                reg = &lt;VOLTD_SCMI_STPMIC1_PWR_SW2&gt;;
                regulator-name = "v3v3_sw";
        };
};

&amp;sdmmc1 {
        pinctrl-names = "default", "opendrain", "sleep";
        pinctrl-0 = &lt;&amp;sdmmc1_b4_pins_a &amp;sdmmc1_clk_pins_a&gt;;
        pinctrl-1 = &lt;&amp;sdmmc1_b4_od_pins_a &amp;sdmmc1_clk_pins_a&gt;;
        pinctrl-2 = &lt;&amp;sdmmc1_b4_sleep_pins_a&gt;;
        cd-gpios = &lt;&amp;gpioh 4 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)&gt;;
        disable-wp;
        st,neg-edge;
        bus-width = &lt;4&gt;;
        vmmc-supply = &lt;&amp;scmi_vdd_sd&gt;;
        status = "okay";
};

/* Wifi */
&amp;sdmmc2 {
        pinctrl-names = "default", "opendrain", "sleep";
        pinctrl-0 = &lt;&amp;sdmmc2_b4_pins_a &amp;sdmmc2_clk_pins_a&gt;;
        pinctrl-1 = &lt;&amp;sdmmc2_b4_od_pins_a &amp;sdmmc2_clk_pins_a&gt;;
        pinctrl-2 = &lt;&amp;sdmmc2_b4_sleep_pins_a&gt;;
        non-removable;
        st,neg-edge;
        bus-width = &lt;4&gt;;
        vmmc-supply = &lt;&amp;v3v3_ao&gt;;
        mmc-pwrseq = &lt;&amp;wifi_pwrseq&gt;;
        #address-cells = &lt;1&gt;;
        #size-cells = &lt;0&gt;;
        status = "okay";

        brcmf: bcrmf@1 {
                reg = &lt;1&gt;;
                compatible = "brcm,bcm4329-fmac";
                interrupt-parent = &lt;&amp;gpiof&gt;;
                interrupts = &lt;0 IRQ_TYPE_LEVEL_HIGH&gt;; /* WL_HOST_WAKE */
                interrupt-names = "host-wake";
        };
};

&amp;spi5 {
        pinctrl-names = "default", "sleep";
        pinctrl-0 = &lt;&amp;spi5_pins_a&gt;;
        pinctrl-1 = &lt;&amp;spi5_sleep_pins_a&gt;;
        status = "disabled";
};

&amp;timers3 {
        /delete-property/dmas;
        /delete-property/dma-names;
        status = "disabled";
        pwm {
                pinctrl-0 = &lt;&amp;pwm3_pins_a&gt;;
                pinctrl-1 = &lt;&amp;pwm3_sleep_pins_a&gt;;
                pinctrl-names = "default", "sleep";
                status = "okay";
        };
        timer@2 {
                status = "okay";
        };
};

&amp;timers4 {
        /delete-property/dmas;
        /delete-property/dma-names;
        status = "disabled";
        pwm {
                pinctrl-0 = &lt;&amp;pwm4_pins_a&gt;;
                pinctrl-1 = &lt;&amp;pwm4_sleep_pins_a&gt;;
                pinctrl-names = "default", "sleep";
                status = "okay";
        };
        timer@3 {
                status = "okay";
        };
};

&amp;timers8 {
        /delete-property/dmas;
        /delete-property/dma-names;
        status = "disabled";
        pwm {
                pinctrl-0 = &lt;&amp;pwm8_pins_a&gt;;
                pinctrl-1 = &lt;&amp;pwm8_sleep_pins_a&gt;;
                pinctrl-names = "default", "sleep";
                status = "okay";
        };
        timer@7 {
                status = "okay";
        };
};

&amp;timers14 {
        status = "disabled";
        pwm {
                pinctrl-0 = &lt;&amp;pwm14_pins_a&gt;;
                pinctrl-1 = &lt;&amp;pwm14_sleep_pins_a&gt;;
                pinctrl-names = "default", "sleep";
                status = "okay";
        };
        timer@13 {
                status = "okay";
        };
};

&amp;uart4 {
        pinctrl-names = "default", "sleep", "idle";
        pinctrl-0 = &lt;&amp;uart4_pins_a&gt;;
        pinctrl-1 = &lt;&amp;uart4_sleep_pins_a&gt;;
        pinctrl-2 = &lt;&amp;uart4_idle_pins_a&gt;;
        /delete-property/dmas;
        /delete-property/dma-names;
        status = "okay";
};

&amp;uart8 {
        pinctrl-names = "default", "sleep", "idle";
        pinctrl-0 = &lt;&amp;uart8_pins_a&gt;;
        pinctrl-1 = &lt;&amp;uart8_sleep_pins_a&gt;;
        pinctrl-2 = &lt;&amp;uart8_idle_pins_a&gt;;
        /delete-property/dmas;
        /delete-property/dma-names;
        status = "disabled";
};

&amp;usart1 {
        pinctrl-names = "default", "sleep", "idle";
        pinctrl-0 = &lt;&amp;usart1_pins_a&gt;;
        pinctrl-1 = &lt;&amp;usart1_sleep_pins_a&gt;;
        pinctrl-2 = &lt;&amp;usart1_idle_pins_a&gt;;
        uart-has-rtscts;
        status = "disabled";
};

/* Bluetooth */
&amp;usart2 {
        pinctrl-names = "default", "sleep", "idle";
        pinctrl-0 = &lt;&amp;usart2_pins_a&gt;;
        pinctrl-1 = &lt;&amp;usart2_sleep_pins_a&gt;;
        pinctrl-2 = &lt;&amp;usart2_idle_pins_a&gt;;
        uart-has-rtscts;
        status = "okay";

        bluetooth {
                shutdown-gpios = &lt;&amp;mcp23017 13 GPIO_ACTIVE_HIGH&gt;;
                compatible = "brcm,bcm43438-bt";
                max-speed = &lt;3000000&gt;;
                vbat-supply = &lt;&amp;v3v3_ao&gt;;
                vddio-supply = &lt;&amp;v3v3_ao&gt;;
        };
};

&amp;usbh_ehci {
        phys = &lt;&amp;usbphyc_port0&gt;;
        status = "okay";
        #address-cells = &lt;1&gt;;
        #size-cells = &lt;0&gt;;
        /* onboard HUB */
        hub@1 {
                compatible = "usb424,2514";
                reg = &lt;1&gt;;
                vdd-supply = &lt;&amp;scmi_v3v3_sw&gt;;
        };
};

&amp;usbotg_hs {
        phys = &lt;&amp;usbphyc_port1 0&gt;;
        phy-names = "usb2-phy";
        usb-role-switch;
        status = "okay";
        port {
                usbotg_hs_ep: endpoint {
                        remote-endpoint = &lt;&amp;con_usb_c_g0_ep&gt;;
                };
        };
};

&amp;usbphyc {
        status = "okay";
};

&amp;usbphyc_port0 {
        phy-supply = &lt;&amp;scmi_vdd_usb&gt;;
        st,current-boost-microamp = &lt;1000&gt;;
        st,decrease-hs-slew-rate;
        st,tune-hs-dc-level = &lt;2&gt;;
        st,enable-hs-rftime-reduction;
        st,trim-hs-current = &lt;11&gt;;
        st,trim-hs-impedance = &lt;2&gt;;
        st,tune-squelch-level = &lt;1&gt;;
        st,enable-hs-rx-gain-eq;
        st,no-hs-ftime-ctrl;
        st,no-lsfs-sc;
};

&amp;usbphyc_port1 {
        phy-supply = &lt;&amp;scmi_vdd_usb&gt;;
        st,current-boost-microamp = &lt;1000&gt;;
        st,decrease-hs-slew-rate;
        st,tune-hs-dc-level = &lt;2&gt;;
        st,enable-hs-rftime-reduction;
        st,trim-hs-current = &lt;11&gt;;
        st,trim-hs-impedance = &lt;2&gt;;
        st,tune-squelch-level = &lt;1&gt;;
        st,enable-hs-rx-gain-eq;
        st,no-hs-ftime-ctrl;
        st,no-lsfs-sc;
};
</code></pre>

<p>&nbsp;</p>
</div>
页: [1]
查看完整版本: 【STM32MP135F-DK】硬件资源测试:玩转GPIO