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

Clarification on nrf_drv_twi_rx being blocking

Hello

nrf_drv_twi_rx and nrf_drv_twi_tx are non blocking calls? 

in the SDK example, I see a while loop is used in the read call for instance which basically is blocking the caller function unless the m_xfer_done flag is set from within an interrupt. Is this how the driver call is typically used...to avoid invoking it before the current read is done?

uint32_t SENSOR::read()
{
    m_xfer_done = false;
    ret_code_t err_code = nrf_drv_twi_rx(&m_twi, MCP9808_ADDR, _buffer, 2);
    
    APP_ERROR_CHECK(err_code);
 
    while(!m_xfer_done);

    return err_code;	         
}

- When I run SystemView while running the app, I see the interrupt is triggered every 11us, and it doesn't even mention the name of the ISR invoked leaving me confused, since SENSOR::read() call is invoked every 3s in my app.

void SENSOR::mainThread()
{
    ret_code_t err_code;

    err_code = nrf_drv_twi_tx(&m_twi, ADDR, &reg, size, false);
    APP_ERROR_CHECK(err_code);
    while (!m_xfer_done);
    while(true)  
{
read();
vTaskDelay(pdMS_TO_TICKS(3000));
}

}

Parents
  • Hi,

    nrf_drv_twi_rx and nrf_drv_twi_tx are non blocking calls?

    The driver supports both blocking and non-blocking (asynchronous) mode, depending on how you initialize it. If you provide an event handler, calls will be non-blocking. See driver documentation for details.

    Is this how the driver call is typically used...to avoid invoking it before the current read is done?

    You typically do not want to busy wait like this as it prevents other (same or lower priority) tasks from running, and it wastes CPU cycles and thus power. In a real application you instead typically want to be in idle while waiting for the interrupt you get when the operation has completed. In other words, both busy waiting (waiting loops) and blocking mode are primarily suitable for as simple as possible demo code and experimentation, but not something you normally want to use in production code.

  • RIght on. Using task notifications sounds like a better approach which seems to be a lightweight version of semaphores in FreeRTOS. After the read call, `ulTaskNotifyTake() to take a semaphore, which supposedly puts the thread into sleep until it's woken up within an twi_handler() via vTaskNotifyGiveFromISR()

    Do you have any idea about the image I shared?

  • Hi,

    I did not see a clear link between the image and the question about TWI to be honest. I do not see anything there, other than as you say you have a interrupt that looks like it happens every 1 ms and that runs for 11.5 us. I cannot say from this what i tis though.

  • twi interrupt is the only interrupt configured in my application and I was curious if you could see if the interrupt info in the screenshot actually relates to twi interrupt handler (doesn't make sense since the interrupt doesn't fire that fast in an application itself) but do you see why could be causing this?

Reply Children
Related