This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Reading and writing to GPIO pins from a sample Zephyr project

I looked at Blinky, but I am still not sure how to access the GPIO pins.  In Blinky, there is an led0 alias, but what about other pins?  What are there aliases?

Specifically, this is what I need to do.

1. I need to read from P0.03, I was told this could handle analog to digital convertesion, because I have analog output going to this pin. 

2. I need to write to P0.27 and P0.26

Any help would be appreciated.

  • Hi, some suggestions for your needs:

    1. I need to read from P0.03, I was told this could handle analog to digital conversion because I have analog output going to this pin.  

    According to the latest nRF52833 Product Specification v1.3, nRF52832 supports 8 ADC channels, P0.03 can be used as AIN1. You are also free to use other ADC channels. This page provides a good example of how to read the analog output based on Zephyr. 

    2. I need to write to P0.27 and P0.26

    You can use device name alias and of course the real device name. For example,  P0.27 come from "GPIO_0" port and with pin number "27", so some functions look like this:

    dev = device_get_binding("GPIO_0");
    ......
    gpio_pin_configure(dev, 27, GPIO_OUTPUT); 
    ......
    while (1)
    {
    
    	gpio_pin_toggle(dev, 27);
    	k_sleep(K_SECONDS(1));
    }

  • Hi! I'm I have been getting a hard time accessing the GPIO's for almost a half day using zephyr via the platformio in VScode and finally with your comment I got it working.

    Can you point me out to the documentation where this GPIO_0 is indicated?

    I'm confused with the device tree model being used by zephyr. I tried reading their API wiki but still confused.

    arduino_header: connector {
    		compatible = "arduino-header-r3";
    		#gpio-cells = <2>;
    		gpio-map-mask = <0xffffffff 0xffffffc0>;
    		gpio-map-pass-thru = <0 0x3f>;
    		gpio-map = <0 0 &gpio0 3 0>,	/* A0 */
    			   <1 0 &gpio0 4 0>,	/* A1 */
    			   <2 0 &gpio0 28 0>,	/* A2 */
    			   <3 0 &gpio0 29 0>,	/* A3 */
    			   <4 0 &gpio0 30 0>,	/* A4 */
    			   <5 0 &gpio0 31 0>,	/* A5 */
    			   <6 0 &gpio0 11 0>,	/* D0 */
    			   <7 0 &gpio0 12 0>,	/* D1 */
    			   <8 0 &gpio0 13 0>,	/* D2 */
    			   <9 0 &gpio0 14 0>,	/* D3 */
    			   <10 0 &gpio0 15 0>,	/* D4 */
    			   <11 0 &gpio0 16 0>,	/* D5 */
    			   <12 0 &gpio0 17 0>,	/* D6 */
    			   <13 0 &gpio0 18 0>,	/* D7 */
    			   <14 0 &gpio0 19 0>,	/* D8 */
    			   <15 0 &gpio0 20 0>,	/* D9 */
    			   <16 0 &gpio0 22 0>,	/* D10 */
    			   <17 0 &gpio0 23 0>,	/* D11 */
    			   <18 0 &gpio0 24 0>,	/* D12 */
    			   <19 0 &gpio0 25 0>,	/* D13 */
    			   <20 0 &gpio0 26 0>,	/* D14 */
    			   <21 0 &gpio0 27 0>;	/* D15 */
    	};

  • Hi

    At the beginning, it seems confusing! but anyway, for working with gpio, zephyr first needs to find a corresponding device:

    dev = device_get_binding("GPIO_0");

    The parameter passed to this function, should be the "label" property of the device you want to work with. it is described here: https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/guides/dts/howtos.html#get-a-struct-device-from-a-devicetree-node

    By searching the devicetree file (.dts), you can see the label of the gpio0 is "GPIO_0":

    		gpio0: gpio@50000000 {
    			compatible = "nordic,nrf-gpio";
    			gpio-controller;
    			reg = < 0x50000000 0x200 0x50000500 0x300 >;
    			#gpio-cells = < 0x2 >;
    			label = "GPIO_0";
    			status = "okay";
    			port = < 0x0 >;
    			phandle = < 0x4 >;

    so the "dev" in the above code will point to the gpio0 and then you can toggle the pins, using the functions defined to work with gpio.

Related