This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] AM620-Q1:MCU GPIO 上升和下降沿触发器问题(从低功耗模式启动)

Guru**** 2416110 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1532493/am620-q1-mcu-gpio-raising-and-failing-edge-trigger-issue-from-low-power-mode

器件型号:AM620-Q1

工具/软件:

尊敬的专家:

客户使用此链接测试 MCU GPIO 从“深度睡眠“或“仅 MCU“模式唤醒。

https://software-dl.ti.com/processor-sdk-linux/esd/AM62X/11_00_09_04/exports/docs/linux/Foundational_Components / Power_Management / pm_low_power_modes.html

-> 3.3.5.4。 深度睡眠
-> 3.3.5.5. 仅 MCU

它们使用相同的 Linux 器件树代码。 (k3-am62x-sk-lpm-wkup-sources.dtso)

唤醒 GPIO 为 MCU_GPIO0_19/MCU_GPIO0_20/MCU_GPIO0_3/MCU_GPIO0_14  

所有这些 GPIO 都存在 上升沿和下降沿唤醒触发问题、即使软件仅设置了“失效触发边沿“也是如此。

 

这是设备树、

// SPDX-License-Identifier: GPL-2.0
/**
 * AM62 family of devices can wakeup from Low Power Modes via
 * multiple wakeup sources. This overlay enables MAIN GPIO, MCU GPIO,
 * and MCU MCAN pins.
 *
 * Copyright (C) 2023 Texas Instruments Incorporated - http://www.ti.com/
 */

/dts-v1/;
/plugin/;

#include <dt-bindings/input/input.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>

#include "k3-pinctrl.h"

&{/} {
	gpio_key {
		compatible = "gpio-keys";
		autorepeat;
		pinctrl-names = "default";
		pinctrl-0 = <&main_gpio1_pins_default>;
		//switch {
		//	label = "CAN1_INH_WKGPIO";
		//	linux,code = <KEY_WAKEUP>;
		//	interrupts-extended = <&main_gpio0 4 IRQ_TYPE_LEVEL_LOW>,
		//		<&main_pmx0 0x010>;
		//	interrupt-names = "irq", "wakeup";
		//};
//
		//switch1 {
		//	label = "CAN0_INH_WKGPIO";
		//	linux,code = <144>;
		//	interrupts-extended = <&main_gpio0 5 IRQ_TYPE_LEVEL_LOW>,
		//		<&main_pmx0 0x014>;
		//	interrupt-names = "irq", "wakeup";
		//};
	};

	mcu_gpio_key {
		compatible = "gpio-keys";
			autorepeat;
		pinctrl-names = "default";
		pinctrl-0 = <&wake_mcugpio1_pins_default>;
		interrupt-parent = <&mcu_gpio0>;
		interrupts = <19 IRQ_TYPE_EDGE_FALLING>,
					<20 IRQ_TYPE_EDGE_FALLING>,
					<3 IRQ_TYPE_EDGE_FALLING>,
					<14 IRQ_TYPE_EDGE_FALLING>;
		switch {
			label = "WNC_SOC_MCUGPIO";
			linux,code = <143>;
			gpios = <&mcu_gpio0 19 GPIO_ACTIVE_LOW>;
			wakeup-source;
		};
		//mark test this
		switch1 {
			label = "IG_ON_MCUGPIO";
			linux,code = <144>;
			gpios = <&mcu_gpio0 20 GPIO_ACTIVE_LOW>;
			wakeup-source;
		};

		switch2 {
			label = "ECALL_MCUGPIO";
			linux,code = <145>;
			gpios = <&mcu_gpio0 3 GPIO_ACTIVE_LOW>;
			wakeup-source;
		};

		switch3 {
			label = "INH_MCUGPIO";
			linux,code = <146>;
			gpios = <&mcu_gpio0 14 GPIO_ACTIVE_LOW>;
			wakeup-source;
		};
	};
};

&main_pmx0 {
	main_gpio1_pins_default: main-gpio1-pins-default {
		pinctrl-single,pins = <
			//AM62X_IOPAD(0x010, 0x28054187, 7) /* (G17) OSPI0_D1.GPIO0_4 */
			//AM62X_IOPAD(0x014, 0x28054187, 7) /* (F21) OSPI0_D2.GPIO0_5 */
		>;
	};
};

&mcu_pmx0 {
	wake_mcugpio1_pins_default: wake-mcugpio1-pins-default {
		pinctrl-single,pins = <
			AM62X_MCU_IOPAD(0x0050, PIN_INPUT , 7) /* (A9) WKUP_I2C0_SDA.MCU_GPIO0_20 */
			AM62X_MCU_IOPAD(0x004C, PIN_INPUT , 7) /* (E9) WKUP_I2C0_SCL.MCU_GPIO0_19 */
			AM62X_MCU_IOPAD(0X000C, PIN_INPUT , 7) /* (E8) MCU_SPI0_D0.MCU_GPIO0_3 */
			AM62X_MCU_IOPAD(0x0038, PIN_INPUT , 7) /* (E8) MCU_SPI0_D0.MCU_GPIO0_14 */
		>;
	};

	mcu_mcan0_tx_pins_default: mcu-mcan0-tx-pins-default {
		pinctrl-single,pins = <
			AM62X_IOPAD(0x034, PIN_OUTPUT, 0) /* (D6) MCU_MCAN0_TX */
		>;
	};

	mcu_mcan0_rx_pins_default: mcu-mcan0-rx-pins-default {
		pinctrl-single,pins = <
			AM62X_IOPAD(0x038, PIN_INPUT, 0) /* (B3) MCU_MCAN0_RX */
		>;
	};

	mcu_mcan0_rx_pins_wakeup: mcu-mcan0-rx-pins-wakeup {
		pinctrl-single,pins = <
			AM62X_IOPAD(0x038, PIN_INPUT | WKUP_EN, 0) /* (B3) MCU_MCAN0_RX */
		>;
	};

	mcu_mcan1_tx_pins_default: mcu-mcan1-tx-pins-default {
		pinctrl-single,pins = <
			AM62X_IOPAD(0x03c, PIN_OUTPUT, 0) /* (E5) MCU_MCAN1_TX */
		>;
	};

	mcu_mcan1_rx_pins_default: mcu-mcan1-rx-pins-default {
		pinctrl-single,pins = <
			AM62X_IOPAD(0x040, PIN_INPUT, 0) /* (D4) MCU_MCAN1_RX */
		>;
	};

	mcu_mcan1_rx_pins_wakeup: mcu-mcan1-rx-pins-wakeup {
		pinctrl-single,pins = <
			AM62X_IOPAD(0x040, PIN_INPUT | WKUP_EN, 0) /* (D4) MCU_MCAN1_RX */
		>;
	};

	mcu_uart0_pins_default: mcu-uart0-pins-default {
		pinctrl-single,pins = <
			AM62X_MCU_IOPAD(0x001c, PIN_INPUT, 0) /* MCU_UART0_CTSn */
			AM62X_MCU_IOPAD(0x0020, PIN_OUTPUT, 0) /* MCU_UART0_RTSn */
			AM62X_MCU_IOPAD(0x0018, PIN_OUTPUT, 0) /* MCU_UART0_TXD */
		>;
	};

	mcu_uart0_rxd_pins_default: mcu-uart0-rxd-pins-default {
		pinctrl-single,pins = <
			AM62X_MCU_IOPAD(0x0014, PIN_INPUT, 0) /* MCU_UART0_RXD */
		>;
	};

	mcu_uart0_rxd_pins_wakeup: mcu-uart0-rxd-pins-wakeup {
		pinctrl-single,pins = <
			AM62X_MCU_IOPAD(0x0014, PIN_INPUT | WKUP_EN, 0) /* MCU_UART0_RXD */
		>;
	};
};

&mcu_gpio0 {
	status = "okay";
};

&mcu_gpio_intr {
	status = "okay";
};

&mcu_mcan0 {
	pinctrl-names = "default", "wakeup";
	pinctrl-0 = <&mcu_mcan0_tx_pins_default>, <&mcu_mcan0_rx_pins_default>;
	pinctrl-1 = <&mcu_mcan0_tx_pins_default>, <&mcu_mcan0_rx_pins_wakeup>;
	status = "disabled";
};

&mcu_mcan1 {
	pinctrl-names = "default", "wakeup";
	pinctrl-0 = <&mcu_mcan1_tx_pins_default>, <&mcu_mcan1_rx_pins_default>;
	pinctrl-1 = <&mcu_mcan1_tx_pins_default>, <&mcu_mcan1_rx_pins_wakeup>;
	status = "disabled";
};

&mcu_uart0 {
	pinctrl-names = "default", "wakeup";
	pinctrl-0 = <&mcu_uart0_pins_default>, <&mcu_uart0_rxd_pins_default>;
	pinctrl-1 = <&mcu_uart0_pins_default>, <&mcu_uart0_rxd_pins_wakeup>;
	status = "disabled";
};

我们以 MCU_GPIO0_20 为例。

我认为 pinmux 可以。

我们让 GPIO 在 INIT 状态下保持低电平、然后触发高电平(上升沿)、即使是软件设置 故障边沿、也会触发唤醒事件。

我们可以看到没有反弹问题。

然后、让 GPIO 在初始化状态下保持高电平、然后触发低电平(下降沿)、从而触发唤醒事件。

我们还可以看到、没有反弹问题。

SW:10.0、我们仅在 Linux 端设置 wakup 源代码。

我有什么遗漏吗?

非常感谢

Gibbs

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗨、Gibbs、

    GPIO 中断与 GPIO 唤醒事件之间的差异

    如 TRM 中所述、GPIO 能够处理由上升沿和下降沿引起的中断。 请参阅 AM62x TRM: https://www.ti.com/lit/pdf/spruiv7 中的第 12.2.1.1.1 节 GPIO 特性

    对于用于从低功耗模式唤醒源的 GPIO、情况并非如此。 当 SoC 处于 DEEP SLEEP 或仅 MCU 模式时、GPIO 引脚多路复用的焊盘将搜索信号的任何变化。 这意味着从硬件的角度来看、它无法区分上升沿和下降沿、而只是知道焊盘上存在信号变化而导致唤醒。

    由于硬件无法确定上升沿或下降沿、因此它不会遵循器件树叠加层中定义的内容。

    上升沿和下降沿器件树定义将适用于一般 GPIO 中断、但不适用于唤醒事件。  


    可能的解决方案

    应该可以将一个上拉电阻连接到 GPIO、以使信号保持在高电平。 然后、将信号接地一段时间、以触发唤醒事件。

    或者、您也可以尝试使用内部 PADCONFIG 拉电阻器、但请注意、这会是一个弱电阻器。 这可以通过设置位 16 = 0 和位 17 = 1 (PADCONFIG = 0x60007) 来实现、以便信号在深度睡眠状态下保持高电平、然后将信号接地以唤醒器件。

    在这些解决方案中的任何一种解决方案中、信号在深度睡眠状态下都将处于高电平、因此它将忽略任何上升沿信号变化、并仅响应下降沿信号变化。

    当 SoC 未处于深度睡眠/MCU 仅模式时、这些 GPIO 信号有什么作用?

    谢谢、

    Anshu

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗨、Gibbs、

    如果您选择启用内部 PADCONFIG 上拉电阻器、则可以从器件树的引脚多路复用节点 ( https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/tree/arch/arm64/boot/dts/ti/k3-pinctrl.h?h=ti-linux-6.6.y) 启用该电阻器

    谢谢、

    Anshu