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

Multiple nrf_drv_twi_tx fails in nrf52

Hi,

I'm using the PCA1040 with the SDK11.0.0. For now I'm trying to communicate with the TWI as the example twi_sensor indicates. The problem comes when I try to do two nrf_drv_twi_tx in a row. The second APP_ERROR_CHECK makes a reset on the chip:

void initial_configuration(void)
{
    ret_code_t err_code;

    err_code =  register_write((uint8_t)(0x02), (uint8_t)(0x00));
    APP_ERROR_CHECK(err_code);

    err_code =  register_write((uint8_t)(0x08), (uint8_t)(0x04));
    APP_ERROR_CHECK(err_code);

    err_code =  register_write((uint8_t)(0x09), (uint8_t)(0x00));
    APP_ERROR_CHECK(err_code);

The write function is as follows:

ret_code_t register_write(uint8_t register_address, uint8_t value)
{
    uint8_t device_address=0x47;
    uint8_t w2_data[2];
    w2_data[0] = register_address;
    w2_data[1] = value;

    return nrf_drv_twi_tx(&m_twi, device_address, (const uint8_t* )(w2_data), sizeof(w2_data), false);  
}

I've read here that is not possible to do following calls to nrf_drv_twi_tx on this SDK version devzone.nordicsemi.com/.../

Could you explain a little more how to merge the data when I have to do multiple nrf_drv_twi_tx in the same section as the previous answer outlines?

Thanks, JosePastor23

  • Hi

    First you should find out why APP_ERROR_CHECK() is resetting your chip. This is pretty easy and described here.

    I don't think the discussion you link to is relevant in your case. They are discussing how to send two buffers consecutively without having to send a repeated start in between the buffers. This would be very handy if you for example wanted to write 4 bytes starting at e.g. register 0x01 in your slave. Then ideally, your transmission would look like this:

    SLAVE_ADDRESS + write bit
    Register address (0x01)
    data[0]
    data[1]
    data[2] 
    data[3]
    

    However, in reality it looks like this:

    SLAVE_ADDRESS + write bit
    Register address (0x01)
    SLAVE_ADDRESS+ write bit (repeated start)
    data[0]
    data[1]
    data[2] 
    data[3]
    

    Then, in many cases, the slave will interpret data[0] as the internal address to be written to. This was no issue on nRF51 and SDK 10, but there is a limitation in the TWIM hardware on nRF52.

    In your case however, it looks like you want to write one byte to three separate registers. Then you will have to send repeated starts anyway so that the slave understands that you want to write to a new register. I don't know how you have configured your TWI, but if you have configured it to use an interrupt handler, you will run into troubles when calling nrf_drv_twi_tx() without any delays in between as you do in your code. Without a delay you are not allowing a transfer to complete before you start the next one. If you don't use an interrupt handler nrf_drv_twi_tx() should work in blocking mode and your code should work alright. If you want to use a handler you need to find some way of allowing one transfer to complete before you start the next one. One common way to do this is to set a flag in the handler and wait for the flag to be set before you start a new transfer.

    If you are in fact using blocking mode then this is an indication of a hardware issue and I would suggest that you take a look at some of the other TWI Q&As on the forum to see if you can find a solution. I think we have covered pretty much all possible TWI errors on the forum.

    Finally, here is a very simple example to try just to see if you have contact with your slave.

  • omg, your slave-finding code is so useful! Thank you!

Related