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

TWI - NRF_ERROR_BUSY with nRF52832 and s132

Hi,

I have recently inherited a project from a former worker. The code intends to read data from a peripherial through TWI (the peripherial is a Si7053 digital temperature sensors from Silicon Labs).

I am using the dev board PCA10040 v 1.1.1 2017.1. I am compiling the code with gcc and using Eclipse Mars.2 (4.5.2).

I was not getting the expected values form the readings so first I tried the peripherial in a Arduino Board and it works properly (peripherial issue discarded). Then I debbuged the app with gdb and I found the problem:

the nrf_drv_twi_rx (infocenter.nordicsemi.com/index.jsp function is returning a NRF_ERROR_BUSY, so I guess it is not reading properly.

This is the function:

bool twi_read_register (uint8_t * reg, uint8_t * p_data, uint8_t length_reg, uint8_t length_data) {

	// Variables
    uint32_t err_code;
    uint32_t timeout = TWI_TIMEOUT;

    // Enable TWI
    nrf_drv_twi_enable(&m_twi_instance);

    // Transfer the address of the device to read data from it
    err_code = nrf_drv_twi_tx(&m_twi_instance, ADDRESS, reg, length_reg, false);

    // Check if error in transfer
    if(err_code != NRF_SUCCESS) return false;

    // Wait until twi_tx done flag change or timeout
    while((!twi_tx_done) && --timeout);
    if(!timeout) return false;

    twi_tx_done = false;

    // Receive data from the sensor
    err_code = nrf_drv_twi_rx(&m_twi_instance, ADDRESS, p_data, length_data);

    // Check if error when receiving
    if(err_code != NRF_SUCCESS) return false;

    // Wait until twi_rx done flag change or timeout
    timeout = TWI_TIMEOUT;
    while((!twi_rx_done) && --timeout);
    if(!timeout) return false;

    twi_rx_done = false;

    return true;
}

//ADRESS = 0x40
//reg = 0xE3
//length_reg = 1
//length_data = 2

I am quite lost. Any help would be welcome.

  • Have you tried setting the no_stop parameter of nrf_drv_twi_tx to true? It looks from the datasheet of the device that it does not expect a stop condition until after rx. Have you checked with a logic analyzer if anything is happening on the TWI bus? Could you post the TWI handler where twi_tx_done flag is set? Which SDK version are you using?

  • Thanks for the fast reply Jørgen. Yes, I have tried setting the no_stop parameter of nrf_drv_twi_tx to true, and the response is exactly the same. I haven't checked with the logic analyzer because I don't have one at work, but I'll use my own one and come back soon with a screenshot. Here you have the TWI handler . I am using: nRF5_SDK_13.0.0_04a0bfd I hope to be this what you asked for. Again, thank you for your help.

  • Update: I was able to find the focus of the problem. It was not the nrf_drv_twi_rx like I thought. In another function named init_sensor() i call the twi_read_register() function several times to log the data of the sensor (model, firmware version, etc.) And the readings are correct. I tried to change the command, instead reading the firmware I changed it to read the temperature and the result was as expected, correct. Therefore, the problem is somewhere between the init_sensor() call and the init_advertising() call. I will post where as soon as I find it.

  • Update: Okay this is weird. I was doing some tests and I made the code to read from the sensor once before entering the "advertising loop". Now, when I'm debugging the code in the board, it works properly, I got more than 20 correct readings before stopping the debug. Then, I thought that was it, so I ran the code in the board, without debug, and it returned wrong readings again. Without changing anything, I debugged again, and the readings were okay again. So, can this be a problem of the interrupt handler? I set up the timer of the interruptd at 30 seconds, to simulate the time I took between readings in the debug mode. therefore is not a time problem, am I right?

  • Current status: The code works properly when debugging, but for some reason it doesn't when running normally. In the debbuging process there is only one breakpoint in the nrf_drv_twi_rx call. I atach here the TWI Initialization function, the handler is in a previous comment. I already tried changing the priority of the interrupts and puting a "delay" before and after the call of nrf_drv_twi_rx. Nothing worked. There is some timing issue here, that's obvious, but where?

Related