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

TWI restart condition after a rx operation (IQS263)

Hello,

I need to interface with a touch sensor from Azoteq (IQS263). This device allows a communication window during which you can read or write on I2C. The issue is that the sensors closes the communication window as soons as it detects a stop condition. As a result, i cannot read several registers from it during this communication window (only one, then i get NACK). From i can see, the SDK16 does not allow restart condition after a rx operation.

Is there a way to solve this issue ? If someone has already face it, feel free to share Slight smile

Best regards,

Aurélien

Parents Reply Children
  • The TWI hardware may operate in two modes; legacy TWI mode (where each byte is loaded from the CPU) and TWIM mode (where each transfer is started using EasyDMA). The mode is controlled by TWI0_USE_EASY_DMA. When using legacy mode you are including the api from nrf_twi.c and not nrfx_twim.c. I would think that using legacy is the preferred here to have better control over this, so make sure that is the case when you are modifying.

    If that doesn't work, I can also find that in \components\drivers_nrf\twi_master\deprecated there are both older hardware and software implementation that may give better low level control of this. Though they are using hardcoded PPI channels, so you may need to modify that to use one that is available in your application.

    Best regards,
    Kenneth

  • Thank's for these informations. I tried to modify the legacy driver : nrfx_twi.c file in that way : 

    extern bool rx_no_stop;
    static bool twi_receive_byte(NRF_TWI_Type         * p_twi,
                                 twi_control_block_t  * p_cb)
    {
        if (p_cb->bytes_transferred < p_cb->curr_length)
        {
            p_cb->p_curr_buf[p_cb->bytes_transferred] = nrf_twi_rxd_get(p_twi);
            ++(p_cb->bytes_transferred);
    
            if ((p_cb->bytes_transferred == p_cb->curr_length - 1) && (!TWI_FLAG_SUSPEND(p_cb->flags)))
            {
                nrf_twi_shorts_set(p_twi, NRF_TWI_SHORT_BB_STOP_MASK);
            }
            else if (p_cb->bytes_transferred == p_cb->curr_length && (!TWI_FLAG_SUSPEND(p_cb->flags)))
            {
                if (rx_no_stop)
                {
                    nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_SUSPEND);
                    p_cb->prev_suspend = TWI_SUSPEND_RX;
                }
                return true;
            }
            else if (p_cb->bytes_transferred == p_cb->curr_length && TWI_FLAG_SUSPEND(p_cb->flags))
            {
                p_cb->prev_suspend = TWI_SUSPEND_RX;
                return false;
            }
            nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_RESUME);
        }
        return true;
    }

    but without success.

    I tried also to use the deprecated driver but unfortunatly it is still not working. Im still having  a stop sent at the end of my RX ...

  • Hmm.. For sure the deprecated software implementation should be able to do this. Have you tried that one also?

    Best regards,
    Kenneth

  • Hello Kenneth,

    I succeeded to make what i want by modifying the current driver in the SDK16 and also with the deprecated driver but i'm facing other issues with the IQS263 that is internaly reseting because of stalling on I2C line. For instance, now, i'm only doing a single read on each event (and not 3 as i wanted at the beginnig) ...

    Regards

Related