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

P0.18 resets device if driven high

I have an input connected to P0.18 on my nRF52832, which needs to be driven high by an external source.  I am running into two problems, which may or may not be related:

1) If I configure it as follows, with either NRF_GPIO_PIN_NOPULL or NRF_GPIO_PIN_PULLDOWN, and then drive that input high, a large amount of current passes through the pin, and the device resets due to low supply voltage. Here is that configuration:

nrf_drv_gpiote_in_config_t trigger_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(false);
trigger_config.pull = NRF_GPIO_PIN_NOPULL;
err_code = nrf_drv_gpiote_in_init(TRIGGER_INTERRUPT_PIN, &trigger_config, in_pin_handler);
APP_ERROR_CHECK(err_code);
nrf_drv_gpiote_in_event_enable(TRIGGER_INTERRUPT_PIN, true);
APP_ERROR_CHECK(err_code);

2) I want to use a handler for this ("B") and a second input ("A").  If I configure P0.18 with a pull-up, and then drive it low (by shorting the pin to ground), there's no reset.  However an interrupt on B will make the gpiote miss the next interrupt on A, i.e. the interrupt will not be called when A goes from low to high.  Here is that configuration, along with the handler:

static void gpio_init(){
	ret_code_t err_code;
	err_code = nrf_drv_gpiote_init();

	nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_LOTOHI(false);
	in_config.pull = NRF_GPIO_PIN_NOPULL;

	err_code = nrf_drv_gpiote_in_init(GYRO_INTERRUPT_PIN, &in_config, in_pin_handler);
	APP_ERROR_CHECK(err_code);

	nrf_drv_gpiote_in_config_t trigger_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(false);
	trigger_config.pull = NRF_GPIO_PIN_NOPULL;
	err_code = nrf_drv_gpiote_in_init(TRIGGER_INTERRUPT_PIN, &trigger_config, in_pin_handler);
	APP_ERROR_CHECK(err_code);
	nrf_drv_gpiote_in_event_enable(TRIGGER_INTERRUPT_PIN, true);
	APP_ERROR_CHECK(err_code);
}


void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action){
	//ret_code_t ret_code = NRF_SUCCESS;
	if(pin == GYRO_INTERRUPT_PIN){
		if(action == NRF_GPIOTE_POLARITY_LOTOHI){
			//read_gyro_fifo();
			//printf("Low -> High!\r\n");
			task_flags |= (1<<TASK_POLL_GYRO);
		}else if(NRF_GPIOTE_POLARITY_HITOLO){
			//printf("High -> Low!\r\n");
		}else{
			//printf("Toggle!\r\n");
		}

	}else{
		printf("t\r\n");
	}
}

So I have two questions:

  1. Is there something special about P0.18?  I haven't run into any of these types of issues on other gpio pins.
  2. Is it possible for the gpiote library from the SDK to somehow miss one pin changing while it's running the handler for another pin?

EDIT: If I configure the pin just as a plain input, without GPIOTE, and poll it, I see the same problems as in #1 above--if it's configured with a pull-up, it's fine, but if it has a pull-down or NOPULL, it resets when driven high.

EDIT #2: I believe I have resolved issue #1.  Should I post the second issue separately?

Parents
  • What is connected to SWO? I ask since it may be connected to a debug tool or other device, since SWO happens to be P0.18 and is used as an output for debug ot trace, see below; if the pin is driving high and it is pulled low externally it can force the power rail into current limit which causes the voltage dip and subsequent device reset.

    void SystemInit(void)
    {
        /* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product
           Specification to see which one). */
        #if defined (ENABLE_SWO)
            CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
            NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Serial << CLOCK_TRACECONFIG_TRACEMUX_Pos;
            NRF_P0->PIN_CNF[18] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
        #endif
    
        /* Enable Trace functionality. If ENABLE_TRACE is not defined, TRACE pins will be used as GPIOs (see Product
           Specification to see which ones). */
        #if defined (ENABLE_TRACE)
            CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
            NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Parallel << CLOCK_TRACECONFIG_TRACEMUX_Pos;
            NRF_P0->PIN_CNF[14] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
            NRF_P0->PIN_CNF[15] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
            NRF_P0->PIN_CNF[16] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
            NRF_P0->PIN_CNF[18] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
            NRF_P0->PIN_CNF[20] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
        #endif
    

  • I looked into that earlier.  ENABLE_SWO is not defined anywhere in the project as far as I can tell (Eclipse has it greyed out).  Nothing else is connected to that pin--it's on an external target, so only VTG, GND, SWDIO and SWCLK are connected to anything external.

  • I don't mean to be pedantic, but the definitions are not in c or h files but in the project file - if used; I know someone was caught out by this (ie me). Your scenario matches exactly ..

Reply Children
  • Depends on the project/compiler/IDE .. an exhaustive search tool is useful, either with find or grep. eg:

    f ENABLE_SWO

    generates stuff like this:

    Search Results: 
    // ENABLE_SWO activates SWO pin, otherwise SWO pin is available as GPIO
        /* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product
        #if defined (ENABLE_SWO)
        /* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product
        #if defined (DEVELOP_IN_NRF52832) && defined (ENABLE_SWO)
        /* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product
        #if defined (ENABLE_SWO)
    
    

    f CONFIG_GPIO_AS_RESET

    Search Results: 
    // Notes on Reset Pin - CONFIG_GPIO_AS_PINRESET
    // If CONFIG_GPIO_AS_PINRESET is defined in the project SystemInit() will set this pin to nReset
    // CONFIG_GPIO_AS_PINRESET activates pin reset, otherwise pin nRESET is available as GPIO
              <state>CONFIG_GPIO_AS_PINRESET</state>
              <state>CONFIG_GPIO_AS_PINRESET</state>
                        <state>CONFIG_GPIO_AS_PINRESET</state>
                        <state>CONFIG_GPIO_AS_PINRESET</state>
    #define CONFIG_GPIO_AS_PINRESET 1
                  <Define> BOARD_PCA10040 CONFIG_GPIO_AS_PINRESET NRF52 NRF52832_XXAA NRF52_PAN_74 NRF_SD_BLE_API_VERSION=5 S132 SOFTDEVICE_PRESENT SWI_DISABLE0</Define>
                  <MiscControls> --cpreproc_opts=-DBOARD_PCA10040,-DCONFIG_GPIO_AS_PINRESET,-DNRF52,-DNRF52832_XXAA,-DNRF52_PAN_74,-DNRF_SD_BLE_API_VERSION=5,-DS132,-DSOFTDEVICE_PRESENT,-DSWI_DISABLE0</MiscControls>
                  <Define> BOARD_PCA10040 CONFIG_GPIO_AS_PINRESET NRF52 NRF52832_XXAA NRF52_PAN_74 NRF_SD_BLE_API_VERSION=5 S132 SOFTDEVICE_PRESENT SWI_DISABLE0</Define>
    CFLAGS += -DCONFIG_GPIO_AS_PINRESET
    ASMFLAGS += -DCONFIG_GPIO_AS_PINRESET
              <state>CONFIG_GPIO_AS_PINRESET</state>
              <state>CONFIG_GPIO_AS_PINRESET</state>
                  <state>CONFIG_GPIO_AS_PINRESET</state>
                        <state>CONFIG_GPIO_AS_PINRESET</state>
                        <state>CONFIG_GPIO_AS_PINRESET</state>
                                <state>CONFIG_GPIO_AS_PINRESET</state>
                        <state>CONFIG_GPIO_AS_PINRESET</state>
                        <state>CONFIG_GPIO_AS_PINRESET</state>
              <state>CONFIG_GPIO_AS_PINRESET</state>
              <state>CONFIG_GPIO_AS_PINRESET</state>
        /* Configure GPIO pads as pPin Reset pin if Pin Reset capabilities desired. If CONFIG_GPIO_AS_PINRESET is not
        #if defined (CONFIG_GPIO_AS_PINRESET)
    etc etc

    Have to edit my search batch file f.bat to add in GCC and other compilers files to search:

    echo Search Results: >SearchResult.txt
    for /R %%f in (*.c *.h *.asm *.s *.src *.eww *.ewp *.uvmpw *.uvproj makefile) DO type %%f | find /I "%1" >> SearchResult.txt
    

Related