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

TWI problem for Nrf51

Hello,

I am working on TWI master application on a nRF51 board, with a sensor associated.

I have often a problem while the reception sequence.

My application:

-> nrf_drv_twi_tx(adr_reg, no_stop)

-> nrf_drv_twi_rx(2 bytes)

So, I want to do a tx message with address register to read two bytes. I managed to have these two bytes sometimes. I check it with a scope.

But, for an unknown reason, I have often an EVENTS_STOPPED at the end of the first byte read. I even can't see all the 8 clock pulses (7 clock pulses often).

This EVENTS_STOPPED break the sequence for an unknow reason. ERROR_SRC is equal to 0 in debug.

I see that the sensor acknowledge each times while it is needed.

SDK 12.3.0

Have you an idea of the reason of this problem?

Thanks.

Parents
  • It is difficult to say why it is failing since I can't see all the arguments for the twi functions you have provided.

    Typically, in order to read a specific register, you would need to write the register address to the device first:

    nrf_drv_twi_tx(&m_twi, DEVICE_ADDR, reg, sizeof(reg), false);

    Then you are ready to read from that register (be sure that the function above is done executing), which can be done with the following command:

    nrf_drv_twi_rx(&m_twi,DVICE_ADDR, pdata, bytes_to_read);

    Best regards,

    Simon

  • Hi Simon,

    Thank you for the answer. You can see the two commands I use:

    err_code = nrf_drv_twi_tx(&m_twi, TMP102_ADDR, reg, sizeof(reg), true);

    err_code = nrf_drv_twi_rx(&m_twi, TMP102_ADDR, &m_sample[0], sizeof(m_sample));

    I set a true as last argument, in the first command to not have a STOP condition, but a start repeat condition between tx and rx.

    I made more tests. I don't see the problem with a "real" sensor (TMP102). 

    As I must do the slave device too. I use an nRF51 evaluation board to do a TWI software slave application.

    I see that when I don't drive the SDA line from slave side, I don't see the problem (SDA is pull-up).

    I don't understand why when I drive SDA line ( '0' and '1' alternate value), this problem occured on the master device.

    It looks as if when the SDA line is not correctly driven in timings, it occured an error on master side. But as this case is not managed, I stay in IRQ_TWI_Handler(). Do you think that the hardware master TWI, controls the timings on SDA line to detect error?

    Best regards,

  • I add this information:

    When there is a modification of the SDA state while a 'high' level of CLK, the problem occured.

    This is maybe a normal error detection, but my master doesn't managed it at all. I modified the code to leave if this error occured.

    Thanks. Launix.

  • If I understand you right, you are using two nRF51 boards, one as slave and one as master and want to read two bytes from the slave to master. Then, after the first byte is received the error happens, and is due to the slave modifying the SDA line while the clock is high. This shouldn't happen, since only the master is allowed modify SDA while CLK is high, to generate start and stop conditions. I assume this is interpreted as a STOP condition, and breaks the transfer.

    Could you upload your projects? Then I can try to reproduce the error, and try to get to the bottom of it.

    Best regards,

    Simon

Reply
  • If I understand you right, you are using two nRF51 boards, one as slave and one as master and want to read two bytes from the slave to master. Then, after the first byte is received the error happens, and is due to the slave modifying the SDA line while the clock is high. This shouldn't happen, since only the master is allowed modify SDA while CLK is high, to generate start and stop conditions. I assume this is interpreted as a STOP condition, and breaks the transfer.

    Could you upload your projects? Then I can try to reproduce the error, and try to get to the bottom of it.

    Best regards,

    Simon

Children
  • Hello Simon,

    You understood exactly what I try to explain.

    In fact, that was due to error in my TWI's software driver on slave side. I correct the timings for that condition never occurs anymore.

    But, we can imagine that for an unknown reason, it occurs again. I add in the function: twi_transfer() the code below for the moment:

    ...

    ...

        test_loop++;
        
        if ((test_loop>100) && nrf_twi_event_check(p_twi, NRF_TWI_EVENT_STOPPED))
        {
                test_loop = 0;
                nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_STOPPED);
                NRF_LOG_DEBUG("TWI: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWI(NRF_TWI_EVENT_STOPPED));
                return false;
        }
        //
        
        if (do_stop_check && nrf_twi_event_check(p_twi, NRF_TWI_EVENT_STOPPED))
        {
                nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_STOPPED);
                NRF_LOG_DEBUG("TWI: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWI(NRF_TWI_EVENT_STOPPED));
                return false;
        }

        return true;
    }

    Thanks

Related