Principle analysis and pin reuse of NXP i.MX6 GPIO

Project scenario:

Reuse the GPIO pin on the overlooking electronic TW-IMX6DL-EVM development board and share its principle.

Compilation environment and development package: host: Ubuntu 18.04
Cross compiler: arm linux gnueabihf GCC
Development board: TW-IMX6DL-EVM
Linux: Linux-4.1.15

Note: all commands in this article refer to the path of overlooking the official electronic environment, which needs to be changed according to its own actual environment. The platform demonstrated in this paper comes from the overlooking electronic iMX6 ARM embedded platform, which is a core board based on NXP iMX6 ARM processor and supports single core / dual core Cortex-A9.

Solution:

1. GPIO operating principle

1.1 GPIO register

Each GPIO has 8 registers to be configured. The functions of each GPIO register are as follows:
GPIO_DR (Data Register)
When GDIR is set to output, the contents of write DR are used to drive the pin of GPIO, and the contents of read DR return the value stored in DR.
When GDIR is set as input, reading DR returns the status of the given IO pin (PSR data), not DR data.
  
GPIO_GDIR (Data Direction Register) direction control register
Control the direction of GPIO pin, 1 as output and 0 as input. Each bit in the register identifies the direction of a specific pad.
GDIR works only when the corresponding pin is set to GPIO.
  
GPIO_PSR (pad status register) status register
32-bit read-only register. Each bit in the register stores the value of the corresponding pad.
  
GPIO_ICR1, ICR2 interrupt control register
Two 32-bit registers, each two bits in the register controls an intermediate break line, ICR1 control interrupt 0 ~ 15, ICR2 control interrupt 16 ~ 31. The settable values are:

  • 00 interrupt is triggered at low level
  • 01 interrupt is triggered by high level
  • 10 interrupt is triggered by rising edge
  • 11 falling edge trigger during interruption

IMR (Interrupt Mask Register)
32-bit register, each bit is the shielded bit of the corresponding interrupt line, 0 interrupt is shielded and 1 interrupt is enabled.
  
GPIO_ ISR (Interrupt Status Register)
32bit register, each bit is used to specify whether an interrupt occurs on the corresponding interrupt line. When an interrupt occurs, the corresponding bit in this register is set to 1.
  
GPIO_EDGE_SEL(Edge Select Register)
32bit register, covering the configuration of ICR register, and selecting edge as the condition for interrupt triggering.

1.2 IO function operation

Read data from pin:
Configure IOMUX and select GPIO mode;
Configure GPDR of GPIO as input;
Read data from PSR register (or from DR, and the value in PSR will be returned);

Write data to pin:
Configure IOMUX and select GPIO mode;
Configure GPDR of GPIO as output;
Write the value to the Data Register(DR);

Interrupt control:
In addition to the general input/output function, the edge detect logic inside GPIO reflects whether a pad configured as input has undergone state transition.

2. Kernel GPIO operation

The device tree imx6qdl-sabresd.dtsi is the configuration file of the TW-AC6-EVM device. The configuration of GPIO is in pinctrl_ Hog: under the hoggrp tag.
Program listing 1 pin multiplexing for gpio function
Directory: arch/arm/boot/dts/imx6qdl-sabresd.dtsi

&iomuxc {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_hog>;

	imx6qdl-sabresd {
		pinctrl_hog: hoggrp {
			fsl,pins = <
			
				MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x80000000
				MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x80000000
				MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x80000000
				MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x80000000
				MX6QDL_PAD_GPIO_0__CCM_CLKO1    0x130b0
				MX6QDL_PAD_EIM_D22__GPIO3_IO22  0x80000000
				MX6QDL_PAD_EIM_D26__GPIO3_IO26 0x80000000
				MX6QDL_PAD_EIM_CS1__GPIO2_IO24 0x80000000
				MX6QDL_PAD_EIM_A25__GPIO5_IO02 0x80000000
				MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x80000000
				MX6QDL_PAD_EIM_EB3__GPIO2_IO31 0x80000000
				MX6QDL_PAD_SD1_CMD__GPIO1_IO18 0x80000000
				MX6QDL_PAD_EIM_D16__GPIO3_IO16 0x80000000
				MX6QDL_PAD_SD3_RST__GPIO7_IO08	0x80000000
				MX6QDL_PAD_EIM_DA9__GPIO3_IO09 0x80000000
				MX6QDL_PAD_NANDF_CS0__GPIO6_IO11 0x80000000
				MX6QDL_PAD_NANDF_CS1__GPIO6_IO14 0x80000000
				MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x80000000
				MX6QDL_PAD_NANDF_CS3__GPIO6_IO16 0x80000000
				
				MX6QDL_PAD_GPIO_4__GPIO1_IO04  0x80000000 
			>;
		};

Mx6qdl in program listing 1_ Pad type macros are defined in the arch / arm / boot / DTS / imx6q pinfunc. H file.

#define MX6QDL_PAD_EIM_D16__GPIO3_IO16              0x090 0x3a4 0x000 0x5 0x0

The meanings of macros are:

0x090        IOMUXC_SW_MUX_CTL_PAD_EIM_DATA16    mux Register offset address
0x3a4         IOMUXC_SW_PAD_CTL_PAD_EIM_DATA16    pad Register offset address
0x000                                            input Register offset address
0x5          ALT5 — Select signal GPIO3_IO16.    mux Mode of
0x0                                              input type
0x80000000   IOMUXC_SW_MUX_CTL_PAD_EIM_DATA16 The value of is set as the chip default

After that, IMX in drivers/pinctrl/pinctrl-imx.c will be called during kernel initialization_ pinctrl_ parse_ The groups function reads the fsl.pin attribute value and saves it in the list pointer variable. Then, it reads the MUX value in the list_ reg,conf_reg,input_reg and set to mux_mode,config,input_val. For more information about the configuration of the device tree gpio, please read Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt.

If the value of GPIO in the file system is always 0, you need to modify the mx6qdl in the arch / arm / boot / DTS / imx6q pinfunc. H file_ PAD_ EIM_ D16__ GPIO3_ The value of io16 can be seen in the previous section by modifying the pin function register iomuxc_ SW_ The position bit of MUX is 1 and is set to the software forced configuration mode. The modification results are as follows:

#define MX6QDL_PAD_EIM_D16__GPIO3_IO16 0x144 0x514 0x000 0x15 0x0

3. Examples

3.1CAN1 bus pins are multiplexed to GPIO

Open the "26.2 External Signals" chapter of the "IMX6DQRM.pdf" data manual to see the CAN bus I/O signals

Open the imx6qdl-sabresd.dtsi kernel device tree file and search can1 to get the contents as shown in Listing 2:
Program listing 2 can1 related code
Directory: arch/arm/boot/dts/imx6qdl-sabresd.dtsi

&can1 {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_flexcan1>;
	status = "okay"; 
};
		pinctrl_flexcan1: flexcan1grp {
			fsl,pins = <
				MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX        0x17059
				MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX		0x17059
			>;
		};

Delete or comment the two pins in Listing 2 (i.e. the two pins under FSL and pins) to prevent reuse of this pin.
Note: the principle of pin reuse is to add the desired function of the pin in the device tree. You need to remove the previous reuse function and add it directly without reuse function.

From the program listing 2, we can get the can1 read pin. The I/O signal in Figure 1 is KEY_ROW2. KEY_ROW2 is a pin unique flag, which determines whether the pins in the device tree are the same pin.
Search for key in imx6q pinfunc. H header file_ Row2, you can get the contents as shown in program listing 3:

Program listing 3 KEY_ROW2 pin multiplexing
Directory: arch / arm / boot / DTS / imx6q pinfunc. H

#define MX6QDL_PAD_KEY_ROW2__ECSPI1_SS2             0x20c 0x5dc 0x808 0x0 0x1
#define MX6QDL_PAD_KEY_ROW2__ENET_TX_DATA2          0x20c 0x5dc 0x000 0x1 0x0
#define MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX            0x20c 0x5dc 0x7e4 0x2 0x0
#define MX6QDL_PAD_KEY_ROW2__KEY_ROW2               0x20c 0x5dc 0x000 0x3 0x0
#define MX6QDL_PAD_KEY_ROW2__SD2_VSELECT            0x20c 0x5dc 0x000 0x4 0x0
#define MX6QDL_PAD_KEY_ROW2__GPIO4_IO11             0x20c 0x5dc 0x000 0x5 0x0
#define MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE       0x20c 0x5dc 0x88c 0x6 0x1

Pin key can be seen_ Row2 can reuse flexcan1 in addition_ RX can also be multiplexed to GPIO4_IO11 function. Generally, the function of the pin can be seen from the naming suffix of the pin, such as MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX this pin is multiplexed as a can read pin, MX6QDL_PAD_KEY_ROW2__GPIO4_IO11 this pin is multiplexed to GPIO.
Pinctrl in imx6qdl-sabresd.dtsi device tree file_ Add GPIO pin multiplexing under hog: hoggrp tag:
Program listing 4 KEY_ROW2 pin multiplexed into GPIO
Directory: arch/arm/boot/dts/imx6qdl-sabresd.dtsi

&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hog>;

imx6qdl-sabresd {	
pinctrl_hog: hoggrp {
fsl,pins = <
...
MX6QDL_PAD_KEY_ROW2__GPIO4_IO11 0x80000000 /* Pin KEY_ROW2 is multiplexed into GPIO4_IO11 */
>;
}; 
...
};

Multiplexed into gpio, the following config value is 0x80000000 by default, which is a fast configuration. If multiplexed into other function related values, you can refer to the default configured value in the device tree. For example, the value of Serial uart configuration is 0x1b0b1

Keywords: Linux Operating System ARM NXP gpio

Added by chriztofur on Tue, 12 Oct 2021 08:38:43 +0300