2022-04-14
Hello,
In an nRF9160, Zephyr based design I am having trouble to configure the 9160’s GPIOs P0.18 through P0.21. I am successfully utilizing other pins on 9160’s port 0. I can drive a couple of LEDs, and I’m able to drive some other external-to-SiP circuit features such as chip select lines.
The pins I can drive correctly are connected to other components outside the nRF9160 SiP. The four GPIOs in question are brought out to a pin header, but are not tied to any rail or other component.
In board files written in device tree source, and in C code I set up GPIOs in the follow manner, device tree (DTS) shown here first:
Code excerpt - DTS:
------------------------------------------------------------------------
leds {
compatible = "gpio-leds";
red_led: led_1 {
gpios = <&gpio0 4 0>;
label = "RGB red channel";
};
.
.
.
};
signal_and_breakout_pins {
compatible = "gpio-leds";
gpio_breakout_1: breakout_line_1 {
gpios = <&gpio0 18 0>;
label = "GPIO breakout line 1";
};
.
.
.
};
------------------------------------------------------------------------
This first excerpt is part of my board’s “common” dts board file. There are two C-like scopes, one named ‘leds’ and the next named ‘signal_and_breakout_pins’. Both have a DTS “compatible” stanza, which I copied from working examples in Jared Wolff’s ‘nfed’ repository and also note from Nordic Semi ncs 1.6.1 sample Zephyr apps.
In code that’s called early from my app’s void main(void), I follow a Zephyr macro pattern and create a device pointer this way in excerpt 2:
Code excerpt 2 - Zephyr device macros and device pointers:
------------------------------------------------------------------------
#define LED0_NODE DT_ALIAS(led0)
#if DT_NODE_HAS_STATUS(LED0_NODE, okay)
#warning --- --- --- macro evaluating 'led0' dts alias returns true --- --- ---
#define LED0_LABEL DT_GPIO_LABEL(LED0_NODE, gpios)
#define LED0_PIN DT_GPIO_PIN(LED0_NODE, gpios)
#define LED0_FLAGS DT_GPIO_FLAGS(LED0_NODE, gpios)
#else
#warning --- --- --- macro evaluating 'led0' dts alias returns false --- --- ---
#define LED0_LABEL ""
#define LED0_PIN 0
#define LED0_FLAGS 0
#endif
static const struct device *dev_led_red;
static uint32_t app_config__configure_line__led0(void)
{
uint32_t rstatus = ROUTINE_OK;
dev_led_red = device_get_binding(LED0_LABEL);
if ( dev_led_red == NULL )
{ rstatus = ZR__WARNING__FAIL_ON_DEVICE_GET_BINDING; }
if ( rstatus == ROUTINE_OK )
{
rstatus = gpio_pin_configure(dev_led_red, LED0_PIN, GPIO_OUTPUT_ACTIVE | LED0_FLAGS);
if ( rstatus < 0 )
{
rstatus = ZR__WARNING__FAIL_ON_GPIO_PIN_CONFIGURE;
}
}
if ( rstatus == ROUTINE_OK )
{ gpio_pin_set(dev_led_red, LED0_PIN, CUSTOM_APP__PIN_STATE_DEFAULT_START_VALUE__LED0); }
return rstatus;
}
------------------------------------------------------------------------
Here is how I similarly set up for the break out GPIO . . .
Code excerpt 3 - GPIO set up for pin in question:
------------------------------------------------------------------------
#if DT_NODE_HAS_STATUS(GPIO_BREAKOUT_1, okay)
#warning --- --- --- macro evaluating 'aliasgpiobreakout1' dts alias returns true --- --- ---
#define GPIO_BREAKOUT_1_LABEL DT_GPIO_LABEL(GPIO_BREAKOUT_1, gpios)
#define GPIO_BREAKOUT_1_PIN DT_GPIO_PIN(GPIO_BREAKOUT_1, gpios)
#define GPIO_BREAKOUT_1_FLAGS DT_GPIO_FLAGS(GPIO_BREAKOUT_1, gpios)
#else
#warning --- --- --- macro evaluating 'aliasgpiobreakout1' dts alias returns false --- --- ---
#define GPIO_BREAKOUT_1_LABEL ""
#define GPIO_BREAKOUT_1_PIN 0
#define GPIO_BREAKOUT_1_FLAGS 0
#endif
static const struct device *dev_gpio_breakout_1;
static uint32_t module_app_config__configure_line__gpio_breakout_1(void)
{
uint32_t rstatus = ROUTINE_OK;
dev_gpio_breakout_1 = device_get_binding(GPIO_BREAKOUT_1_LABEL);
if ( dev_gpio_breakout_1 == NULL )
{ rstatus = ZR__WARNING__FAIL_ON_DEVICE_GET_BINDING; }
if ( rstatus == ROUTINE_OK )
{
// rstatus = gpio_pin_configure(dev_gpio_breakout_1, GPIO_BREAKOUT_1_PIN, GPIO_OUTPUT_ACTIVE | GPIO_BREAKOUT_1_FLAGS);
rstatus = gpio_pin_configure(dev_gpio_breakout_1, GPIO_BREAKOUT_1_PIN, GPIO_OUTPUT | GPIO_BREAKOUT_1_FLAGS);
if ( rstatus < 0 )
{ rstatus = ZR__WARNING__FAIL_ON_GPIO_PIN_CONFIGURE; }
}
if ( rstatus == ROUTINE_OK )
{ gpio_pin_set(dev_gpio_breakout_1, GPIO_BREAKOUT_1_PIN, CUSTOM_APP__START_VALUE__GPIO_BREAKOUT_1); }
return rstatus;
}
------------------------------------------------------------------------
These GPIO pins are both on port 0 of the nRF9160. But while I can set the output of the LED just fine, I see no change in voltage level on P0.18, the pin I ma using as a test point / break out. Is there something different or special about 9160 GPIOs P0.18 through P0.21?
From the nRF9160 datasheet the only difference I see is that P0.18 can optionally be configured as an analog input. Given this, is there some possible effect that my configuration may be changed or overwritten in a situation where I have the ADC peripheral enabled for my target processor in the board file?