Output driver not working for P1.13 on nRF5340 DK

I am trying to set up two GPIOs to control an external chip. Development and testing is currently using the nRF5340 DK. NCS version is 2.5.0.

In my nrf5340dk_nrf5340_cpuapp.overfile, I have the following. There are other GPIOs, but ignore those for now. Also, ignore the fact that reset should be an open-drain. I am just sanity testing right now. The pins are not connected and only being monitored with a logic analyzer.

/ {
    gpiocustom {
        compatible = "gpio-keys";
        gpiocus1: gpiocus_1 {
            gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
            label = "nRST";
        };
        gpiocus2: gpiocus_2 {
            gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>;
            label = "MFIO";
        };
    aliases {
        max32664reset = &gpiocus1;
        max32664mfio = &gpiocus2;
    };
};

In the code we have:

static const struct gpio_dt_spec gpio_sh_reset = GPIO_DT_SPEC_GET(DT_ALIAS(max32664reset), gpios);
static const struct gpio_dt_spec gpio_sh_mfio = GPIO_DT_SPEC_GET(DT_ALIAS(max32664mfio), gpios);

and then to test it we have the following declarations

    gpio_pin_configure_dt(&gpio_sh_reset, GPIO_OUTPUT_HIGH);
    gpio_pin_configure_dt(&gpio_sh_mfio, GPIO_OUTPUT_HIGH);

and test code

    for(int i = 0; i < 3; i++)
    {
        k_msleep(500);
        gpio_pin_set_dt(&gpio_sh_mfio, 0);
        k_msleep(500);
        gpio_pin_set_dt(&gpio_sh_reset, 0);
        k_msleep(500);
        gpio_pin_set_dt(&gpio_sh_mfio, 1);
        k_msleep(500);
        gpio_pin_set_dt(&gpio_sh_reset, 1);
    }

asd

The MFIO pin (P1.14) moves. The reset pin (P1.13) does not. I have done a lot of tracing to determine exactly where the problem is occurring. It happens at:

reg->PIN_CNF[pin_number] = cnf;

When the pin configuration gets changed from input-with-pullup to output. This is in nrf_gpio_reconfigure() and is occurring in the secure domain at 0x50842a34. The nRF Debug peripheral registers view does not seem to give access to GPIO P1 in the secure domain, so I am using gdb commands in the debug console to set and verify the P1_S registers and observing the result via Saleae logic analyzer. I must do this while still in the nrf driver functions or I lose privilage to access 0x50000000 register range from the debug console.

Here are my observations:

Set P1.13 high via pullup, *((uint32_t*)0x50842a34)=0xC, pin goes high.

Set P1.13 low via pulldown, *((uint32_t*)0x50842a34)=0x4, pin goes low.

Set P1.13 to output, *((uint32_t*)0x50842a34)=0x3, pin goes low and stays low regardless of state of P1->OUT bit 13. I have set and cleared the bit by using *((uint32_t*)0x50842808)=0x2000 and *(uint32_t*)0x5084280c)=0x2000. The pin state does not change. 0x50842a34 verifies that it is in output mode, owned by APP CPU, with drive set to S0S1 (i.e. register = 0x03). When I change P1.14 using *((uint32_t*)0x50842808)=0x4000 and *((uint32_t*)0x5084280c)=0x4000, that pin does change.

One thing I noticed, if I have the pin in input-with-pullup state and then set it to output, it doesn't go straight to 0. It decays to 0 as though it's draining through something (possibly the Saleae?). That's why I suggest that it seems the output driver is not even connected when PIN_CFG[13].DIR is set to output.

I have searched around in the nRF5340 product specification and on the PCA10095 schematic and cannot figure out anything that would be interfering with P1.13.

Parents
  • Assuming your board is based on nrf5340dk, I noticed in boards/arm/nrf5340dk_nrf5340/nrf5340dk_nrf5340_cpunet-pinctrl.dtsi

    spi0_default: spi0_default {
    group1 {
    psels = <NRF_PSEL(SPIM_SCK, 1, 15)>,
    <NRF_PSEL(SPIM_MISO, 1, 14)>,
    <NRF_PSEL(SPIM_MOSI, 1, 13)>;
    };

    This means the pins are assigned to cpunet and settings from the application process wlll not be used.  

  • In the final build/zephyr/zephyr.dts I see that spi4 also has a claim on 0x2D (i.e. P1.13). However, spi4 is disabled in this configuration. That spi4 configuration must be coming from .dtsi files. I wish there was an easier way to view all the pin assignments.

  • Two tips, not sure if either is exactly what you want:

    * In Visual Studio Code in the nRF Connect extension there is an Action called "Devicetree" which allows exploring the device tree files.

    * All the devicetree configuration ends up in

    build_dir/zephyr/include/generated/device_tree_generated.h 

    or for cpunet  in

    build_dir/hci_rpmsg/zephyr/include/generated/device_tree_generated.h

    these files are big and not exactly pretty but I believe they have everything determined from devicetree in it.

    BTW, if you know anyone looking for a developer experienced with zephyr and Nordic's SDK, I'm currently looking for new clients:

    www.linkedin.com/.../

Reply
  • Two tips, not sure if either is exactly what you want:

    * In Visual Studio Code in the nRF Connect extension there is an Action called "Devicetree" which allows exploring the device tree files.

    * All the devicetree configuration ends up in

    build_dir/zephyr/include/generated/device_tree_generated.h 

    or for cpunet  in

    build_dir/hci_rpmsg/zephyr/include/generated/device_tree_generated.h

    these files are big and not exactly pretty but I believe they have everything determined from devicetree in it.

    BTW, if you know anyone looking for a developer experienced with zephyr and Nordic's SDK, I'm currently looking for new clients:

    www.linkedin.com/.../

Children
Related