Problem with initial operation not working when transmitting TWI after wake-up by GPIOTE

hello,

We are implementing the function of sending/receiving via TWI after wake-up by GPIOTE.

The problem is after wake-up by GPIOTE....

The first TWI transmission/reception does not work. (No specific error is returned... only the waveform cannot be observed from the actual port.)

And in the operating state, TWI transmission/reception works normally from the second GPIOTE signal.

SW configuration is

wake-up by GPIOE -> void bsp_event_handler(bsp_event_t event) ->  app_timer_start(m_eventTWI_timer_id, EVENT_TWI_MEAS_INTERVAL, NULL);

-> static void eventTWI_timeout_handler(void * p_context) ->  read_sensor_data() -> Run nrf_drv_twi_rx

void bsp_event_handler(bsp_event_t event)
{
    uint32_t err_code;
    uint8_t mBLE_Send_check = 0;
    printf("> bsp_EH ");

    switch (event)
    {

        case   BSP_EVENT_ADVERTISING_STOP :
         
            printf("> BSP_EVENT_ADVERTISING_STOP\r\n");
           

            break;

       
        case BSP_EVENT_KEY_0 :

            printf("eTouch\r\n");

            m_eventTWI_timer_cnt = 0;
            err_code = app_timer_start(m_eventTWI_timer_id, EVENT_TWI_MEAS_INTERVAL, NULL);
            APP_ERROR_CHECK(err_code);

            //err_code = nrf_drv_twi_tx(&m_twi, PIC_TOUCH_ADDR, TWI_reg, sizeof(TWI_reg), false);
            //PIC_TOUCH_set_mode();
           

            mBLE_Send_check = 1;
           
             break;
   }
}
 

static void eventTWI_timeout_handler(void * p_context)
{
   
    //PIC_TOUCH_set_mode();
    //nrf_delay_us(500);
   
    m_eventTWI_timer_cnt++;
    printf("> TWI_tEH %d\n\r", m_eventTWI_timer_cnt);
    UNUSED_PARAMETER(p_context);

   
     if( m_eventTWI_timer_cnt <= 1 )
     {
        read_sensor_data();
     }
     else
     {
        //m_eventTWI_timer_cnt = 0;    
        app_timer_stop(m_eventTWI_timer_id);    
     }
}

static void read_sensor_data()
{
    m_xfer_done = false;
    uint8_t temp_key = 0;

    /* Read 1 byte from the specified address - skip 3 bits dedicated for fractional part of temperature. */
    ret_code_t err_code = nrf_drv_twi_rx(&m_twi, PIC_TOUCH_ADDR, &m_PIC_Touch_data[0], sizeof(m_PIC_Touch_data) );
    APP_ERROR_CHECK(err_code);
}

After wake-up, there was no effect even if the Timer delay was greatly increased to 500ms or more.

Please check if the first TWI does not run after wake-up.

-----------------------------------------------------------------------------------------------------------------------------------------------------

Additionally, what was discovered during the experiment was

The role of the PCB that currently runs TWI is peripheral, but the above phenomenon is reproduced when it is not connected to central.

However, when connected to central... the problem of not being able to run TWI the first time above disappears.

It operates normally from the first TWI.

Parents Reply Children
  • hello, 

    I am receiving debugging messages for the above behavior.

    Therefore, it was confirmed that normal wake-up occurred for the GPITE signal.


    The actual wake-up occurs normally without any omissions.

    The TWI signal is not generated...

    and

    Do you have any idea why it depends on whether you are registered or not?

    thank

  • Hello,

    ''I am receiving debugging messages for the above behavior.''

    Could you please share the debug output?

  • hello,

    The message that determines wake-up, as I mentioned, is in the code below.

            case BSP_EVENT_KEY_0 :

                printf("eTouch\r\n");

                m_eventTWI_timer_cnt = 0;
                err_code = app_timer_start(m_eventTWI_timer_id, EVENT_TWI_MEAS_INTERVAL, NULL);
                APP_ERROR_CHECK(err_code);

    void bsp_event_handler(bsp_event_t event)
    {
        uint32_t err_code;
        uint8_t mBLE_Send_check = 0;
        printf("> bsp_EH ");
    
        switch (event)
        {
    
            case   BSP_EVENT_ADVERTISING_STOP :
             
                printf("> BSP_EVENT_ADVERTISING_STOP\r\n");
               
    
                break;
    
           
            case BSP_EVENT_KEY_0 :
    
                printf("eTouch\r\n");
    
                m_eventTWI_timer_cnt = 0;
                err_code = app_timer_start(m_eventTWI_timer_id, EVENT_TWI_MEAS_INTERVAL, NULL);
                APP_ERROR_CHECK(err_code);

    if,

    The interval between GPIOE signals is approximately 80ms. (Refer to the waveform above)

    Is this time short enough to complete the TWI transfer?

    Normal) GPIOTE 1st -> TWI 1st -> GPIOTE 2nd -> TWI 2nd

    expectation? ) GPIOTE 1st -> GPIOTE 2nd occurs in the middle of TWI 1st processing -> TWI 2nd -> TWI 1st

    We are preparing for mass production, so it is a very urgent situation. Please help.

  • Hello,

    ''The interval between GPIOE signals is approximately 80ms. (Refer to the waveform above)''. The issue is how long the GPIOTE signals are not the length of interval between the signals. Looking at the waveforms we can say that the 'dips' of the GPIOTE signal is very short. The button detect delay if 50 ms (default value), seems like signals are not entirely pulled down long enough to be detected by button library. 

  • hello

    I also said above that GPIOE's time is not 50ms.

    It's an urgent issue, but the answer came after a long time...

    The basic code has been modified as shown below.

    We confirmed that GPIOE is recognized normally through debugging messages.

    /* GPIOTE event is used only to start periodic timer when first button is activated. */
    static void gpiote_event_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
    {
    uint8_t cnt ;
    
    app_button_cfg_t const * p_btn = button_get(pin); // pin -> configuartion data = app_button_cfg_t type
    bool is_set = nrf_drv_gpiote_in_is_set(p_btn->pin_no); // INPUT CHECK = nrf_gpio_pin_read
    bool is_active = !((p_btn->active_state == APP_BUTTON_ACTIVE_HIGH) ^ is_set); // acticve check
    
    /* If event indicates that pin is active and no other pin is active start the timer. All
    * action happens in timeout event.
    */
    if (is_active && (m_pin_active == 0)) // Key First check = evt_handle(uint8_t pin, uint8_t value)
    // if (is_active && (mButton_Mask == 0))
    {
    // NRF_LOG_DEBUG("First active button, starting periodic timer");
    mPin = p_btn->pin_no;
    
    if( mPin == 3 ) // touch
    {
    m_pin_active = eKey_Process_PU_touch;
    mPin_active_cnt = 0;
    mPin_timer = 0;
    
    }
    :
    :
    }
    
    
    static void detection_delay_timeout_handler(void * p_context)
    {
    
        :
        :
        
        else if( m_pin_active == eKey_Process_PU_touch)   
        {
    
            usr_event( mPin, APP_BUTTON_PUSH );
    
           m_pin_active = eKey_Process_no;
           mPin_active_cnt = 0;
           mPin_timer = 0;
         }
         
        :
        :
    
    
    }

    Please confirm.

Related