portexpander board definition

Hello,

I have a MCP23017 portexpander connected to an nrf9160 board with I2C, can somebody please explain me, how to integrate the GPIOs of the portexpander in the devicetree?

This is the subnode in the I2C node:

portexp: portexp@20 {
        compatible = "microchip,mcp230xx";
        reg = <0x20>;
        gpio-controller;
        #gpio-cells = <2>;
		ngpios = <16>;
       	//interrupt-parent = <&gpio0>;
        //interrupts = <12 IRQ_TYPE_EDGE_RISING>; // You may need to adjust this GPIO number (12) based on your board configuration.
        //interrupt-controller;
        //#interrupt-cells = <2>;

		outputs {
			compatible = "gpio-outputs";
			gpio0: gpio0 {
				compatible = "gpio-out";
				gpio-hog;
				gpio-line-name = "PORTEXP_GPIO0";
				gpios = <&portexp 8 GPIO_ACTIVE_HIGH>;
				output-high;
			};

			gpio1: gpio1 {
				compatible = "gpio-out";
				gpio-hog;
				gpio-line-name = "PORTEXP_GPIO1";
				gpios = <&portexp 9 GPIO_ACTIVE_HIGH>;
				output-high;
			};
		};

		aliases {
			out1 = &gpio0;
			out2 = &gpio1;
		};
    };

I am getting the different erros when testing: "C:/Users/thoma/zephyrproject/zephyr/include/zephyr/devicetree.h:230:32: error: 'DT_N_ALIAS_out1_P_gpios_IDX_0_VAL_pin' undeclared here (not in a function); did you mean 'DT_N_S_leds_S_led_1_P_gpios_IDX_0_VAL_pin'?"
or: devicetree error: 'gpio-hog' is marked as required in 'properties:' in C:/Users/thoma/zephyrproject/zephyr/dts/bindings\gpio\microchip,mcp230xx.yaml, but does not appear in <Node /soc/sercom@42000800/portexp@20/aliases in 'C:/Users/thoma/zephyrproject/zephyr/misc/empty_file.c'>

I've also tried it with another board defintion file as a starting base (Arduino mkr zero with an ATSAMD21G18), but with similar results.

Thank you very much!

Parents
  • based on the thingy:52 I have changed the board definition:

    in the base node of the board:

    outputs {
    	compatible = "gpio-out";
    	out0: out_0 {
    		gpios = <&portexp 8 GPIO_ACTIVE_HIGH>;
    	};
    };

    and the portexpander in the i2c node:

    portexp: portexp@20 {
            compatible = "microchip,mcp230xx";
            reg = <0x20>;
            gpio-controller;
            #gpio-cells = <2>;
    		ngpios = <16>;
           	//interrupt-parent = <&gpio0>;
            //interrupts = <12 IRQ_TYPE_EDGE_RISING>; // You may need to adjust this GPIO number (12) based on your board configuration.
            //interrupt-controller;
            //#interrupt-cells = <2>;
        };

    And the error still happens when calling 

    #define OUT0_NODE DT_ALIAS(out0)
    static const struct gpio_dt_spec out00 = GPIO_DT_SPEC_GET(OUT0_NODE, gpios);
    :

    C:/Users/thoma/zephyrproject/zephyr/include/zephyr/device.h:83:41: error: '__device_dts_ord_DT_N_S_outputs_S_out_0_P_gpios_IDX_0_PH_ORD' undeclared here (not in a function)
    
    C:/Users/thoma/zephyrproject/build/zephyr/include/generated/devicetree_generated.h:1455:29: error: 'DT_N_S_outputs_S_out_0_P_gpios_IDX_0_VAL_pin' undeclared here (not in a function); did you mean 'DT_N_S_leds_S_led_0_P_gpios_IDX_0_VAL_pin'?

Reply
  • based on the thingy:52 I have changed the board definition:

    in the base node of the board:

    outputs {
    	compatible = "gpio-out";
    	out0: out_0 {
    		gpios = <&portexp 8 GPIO_ACTIVE_HIGH>;
    	};
    };

    and the portexpander in the i2c node:

    portexp: portexp@20 {
            compatible = "microchip,mcp230xx";
            reg = <0x20>;
            gpio-controller;
            #gpio-cells = <2>;
    		ngpios = <16>;
           	//interrupt-parent = <&gpio0>;
            //interrupts = <12 IRQ_TYPE_EDGE_RISING>; // You may need to adjust this GPIO number (12) based on your board configuration.
            //interrupt-controller;
            //#interrupt-cells = <2>;
        };

    And the error still happens when calling 

    #define OUT0_NODE DT_ALIAS(out0)
    static const struct gpio_dt_spec out00 = GPIO_DT_SPEC_GET(OUT0_NODE, gpios);
    :

    C:/Users/thoma/zephyrproject/zephyr/include/zephyr/device.h:83:41: error: '__device_dts_ord_DT_N_S_outputs_S_out_0_P_gpios_IDX_0_PH_ORD' undeclared here (not in a function)
    
    C:/Users/thoma/zephyrproject/build/zephyr/include/generated/devicetree_generated.h:1455:29: error: 'DT_N_S_outputs_S_out_0_P_gpios_IDX_0_VAL_pin' undeclared here (not in a function); did you mean 'DT_N_S_leds_S_led_0_P_gpios_IDX_0_VAL_pin'?

Children
  • Hi,

    Can you upload a zip of a simple project showing this?
    Then I will reproduce the issue and see if I can find a solution.

    Regards,
    Sigurd Hellesvik

  • Hi,

    I've worked on the AT SAMD21 version of the board defintion file, but the error is the same on the nrf9160. Here is the blinky sample with the adapted code and the board defition.

    1588.blinky.zip

  • Hi,

    Do you have a bindings file for the gpio-out compatible? I changed it to gpio-leds for now, since that is what I would normally use for output GPIOs. There is nothing about gpio-leds that is strictly related to LEDs, it just provides a bindings file that helps the devicetree system make sense of the node properties.

    Here's an overlay I want you to try with nrf9160dk_nrf9160:

    8640.nrf9160dk_nrf9160.overlay

    It probably needs some more, so let me know which build or runtime errors you are seeing with this overlay and I'll see what I can do.

  • Hello,

    The key was to change it to gpio-leds. I have misunderstood the documentation with the bindings...

    The build works now, but when we try to use it in the main.c, the following error appears:

    c:/users/thoma/zephyr-sdk-0.15.0/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.1.0/../../../../arm-zephyr-eabi/bin/ld.exe: app/libapp.a(main.c.obj): in function `main':
    C:/somepath/blinky/src/main.c:101: undefined reference to `__device_dts_ord_22'
    collect2.exe: error: ld returned 1 exit status
    ninja: build stopped: subcommand failed.
    FATAL ERROR: command exited with status 1: 'C:\Program Files\CMake\bin\cmake.EXE' --build 'C:\Users\thoma\zephyrproject\build'

    This error happens on this line:

    gpio_is_ready_dt(&out00)

    I've disabled the other lines where out00 is used to trace the error...

    main.c

    #include <zephyr/kernel.h>
    #include <zephyr/drivers/gpio.h>
    
    /* 1000 msec = 1 sec */
    #define SLEEP_TIME_MS   1000
    
    #define LED0_NODE DT_ALIAS(led0)
    #define LED1_NODE DT_ALIAS(led1)
    #define LED2_NODE DT_ALIAS(led2)
    #define OUT0_NODE DT_ALIAS(out0)
    
    static const struct gpio_dt_spec led00 = GPIO_DT_SPEC_GET(LED2_NODE, gpios);
    static const struct gpio_dt_spec led01 = GPIO_DT_SPEC_GET(LED1_NODE, gpios);
    static const struct gpio_dt_spec led02 = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
    static const struct gpio_dt_spec out00 = GPIO_DT_SPEC_GET(OUT0_NODE, gpios);
    
    void main(void)
    {
    	int ret;
    
    	printk("### Hello World ###");
    
    	if (!gpio_is_ready_dt(&led00)) {
    		return;
    	}
    	printk("device ready: led00");
    
    	if (!gpio_is_ready_dt(&out00)) {
    		return;
    	}
    	printk("device ready: out00");
    
    	ret = gpio_pin_configure_dt(&led00, GPIO_OUTPUT_ACTIVE);
    	if (ret < 0) {
    		return;
    	}
    	printk("device config: led00");
    
    	//ret = gpio_pin_configure_dt(&out00, GPIO_OUTPUT_ACTIVE);
    	if (ret < 0) {
    		return;
    	}
    	printk("device config: out00");
    
    	while (1) {
    		printk("BLINK\n");
    		ret = gpio_pin_toggle_dt(&led00);
    		if (ret < 0) {
    			return;
    		}
    
    		//ret = gpio_pin_toggle_dt(&out00);
    		if (ret < 0) {
    			return;
    		}
    		k_msleep(SLEEP_TIME_MS);
    	}
    }
    

    So it seems there is an error with the pointer to the devicetree object loaded in GPIO_DT_SPEC_GET

    Thank you!

    BR Thomas

Related