Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Interaction between GPIOTE pin and UART RTS

I have the UART configured using the standard boiler plate code, with flow control enabled, where the RTS output is assigned pin 5.

 I have defined a GPIOTE pin 25 as an output, with its initial state defined as Hi. I then set this output low using nrf_drv_gpiote_out_clear(opPin ); sure enough opPin goes low, however so does RTS.

This is 100% repeatable.

Any ideas?

Parents Reply Children
  • Using on sdk_13.0.0_04a0bfd Based on the UART example.

    Hardware: V1.00

    S/N: 682336494

    I configure the pin 25 thus:

    #define opPin	25
    void io_init( void ) {
        ret_code_t err_code;
        err_code = nrf_drv_gpiote_init();
        APP_ERROR_CHECK(err_code);
    
        /**
         * Output
         */
    	// Where the true specifies the initial state of the O/P line so in  this case Hi
    	nrf_drv_gpiote_out_config_t out_config = GPIOTE_CONFIG_OUT_SIMPLE( true );
    	err_code = nrf_drv_gpiote_out_init(opPin, &out_config);
    	APP_ERROR_CHECK(err_code);
    }
    

    configuring the UART (you will notice the desperate attempts to keep RTS Hi !! even this generates a 1.98us low during the execution of APP_UART_FIFO_INIT):

    static void uart_init() {
        uint32_t err_code;
        const app_uart_comm_params_t comm_params =
          {
              RX_PIN_NUMBER,
              TX_PIN_NUMBER,
              RTS_PIN_NUMBER,
              CTS_PIN_NUMBER,
    		  APP_UART_FLOW_CONTROL_ENABLED,//APP_UART_FLOW_CONTROL_DISABLED,//
              false,
    		  UART_BAUDRATE_BAUDRATE_Baud4800 //UART_BAUDRATE_BAUDRATE_Baud115200
          };
    
        NRF_UART0->TASKS_STOPRX = 1;
        APP_UART_FIFO_INIT(&comm_params,
                             UART_RX_BUF_SIZE,
                             UART_TX_BUF_SIZE,
    						 uart_error_handle,
                             APP_IRQ_PRIORITY_LOWEST,
                             err_code);
        NRF_UART0->TASKS_STOPRX = 1;
        APP_ERROR_CHECK(err_code);
    }

    and then to take opPin Low:

    nrf_drv_gpiote_out_clear( opPin );

    The weird thing is I have also see the same effect caused by the execution of this line:

    SEGGER_RTT_WriteString(0, "Exectuing UART Test\n");

    which is called after the initialisation of UART and IO as seen below in main which a bit of a mess, however if you step through from the start, I see RTS go Low when the opPin is cleared, and No opPin is not connected to RTS!

    int main(void)
    {
    	io_init();
        uart_init();
        NRF_UART0->TASKS_STOPRX = 1;
        nrf_drv_gpiote_out_clear( opPin );
        NRF_UART0->TASKS_STOPRX = 1;
        //SEGGER_RTT_WriteString(0, "Exectuing UART Test\n"); // Print message to RTT to the application flow
        //log_init();
    
        //printf("uart_init\r\n");
        //SEGGER_RTT_printf(0, "uart_init\r\n"); // Print service UUID should match definition BLE_UUID_OUR_SERVICE
        //bsp_board_leds_init();
    
        //SEGGER_RTT_WriteString(0,"io_init\r\n");
        //app_uart_flush();
    
        nrf_drv_gpiote_out_clear( opPin );
        NRF_UART0->TASKS_STOPRX = 1;
        //while( !configComplete ){}
    
        while (true) {
        	// do nothing
        }
    }

    I am suspicious of my sdk_config.h

    3755.sdk_config.h

  • Also see this issue when toggling GPIO lines (as opposed to GPIOTE) for example when calling bsp_board_leds_init(); however on this occasion using sdk14 and Segger Embedded Studio. This time changing the settings of the sdk_config.h via app_config.h

    Help!!

  • Hi,

    I have done some more debugging and I have a question for you: Are you sure this is related to the GPIO and/or the RTT? What happens if you don't do anything after initializing the UART?

    In an attempt to narrow it it down I got as far as this:

    #define OUT_PIN	25
    
    int main(void)
    {    
        NRF_UARTE0->PSEL.RTS = RTS_PIN_NUMBER;
        NRF_UARTE0->ENABLE = 8;    
        NRF_UARTE0->TASKS_STARTRX = 1;
        
        while (true) {
        	
        }
    }

    As you can see it wasn't necessary to toggle any GPIO to make the RTS go low. It was only necessary to start the RX and this also happens inside APP_UART_FIFO_INIT().

    So it might be that this is just expected behaviour. 

  • Thanks for pursuing this.

    I am not sure which component is misbehaving GPIO and/or the RTT. [context] I decided to use a completely unrelated custom (as I thought) IO line (Pin 24 (Pin 25 appeared to have some decoupling)) to control the CTS line on my peripheral as I couldn't get the Nordic RTS line to change and block incoming data. The inability to block incoming data resulted in overrun errors.

    [observation] It was while changing my custom GPIO line, stepping through the code, that I saw the Nordic RTS change state. My custom GPIO line and the Nordic RTS line were/are completely disconnected both physically (not connected electrically) and code. I wouldn't consider this expected behaviour which is why I hi-lighted the issue.

    I have recently made progress using the custom GPIO line as I can change its state (exactly when needed) relative to reseting the peripheral on another GPIO line. I would have preferred not to have used this approach and to have pursued a the conventional configuration.

  • Hi,

    I have debugged some more and I think the problem is that the RX task is enabled inside APP_UART_FIFO_INIT(), as I mentioned earlier. Here is the call stack with the path to the instruction.

    After RX is enabled, the UART feels ready to receive and hence activates the RTS signal. I don't think it is related to neither RTT nor any GPIO actions. At least I'm not able to reproduce that. The enabling of RX is embedded quite deep into the app_uart library and I couldn't find a way to cheat it. Hence I think you need to keep doing what you describe above, or drop the app_uart library and use the UART drivers directly.

Related