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
  • Hi,

    Thank you very much for the reply. The NO_STOP flag seems to be available only for TX mode, not RX mode !

  • Looks like you are right. Then I suppose it may be possible by calling nrfx_twi_xfer()/nrfx_twim_xfer() directly, instead of using the nrf_drv_twi_rx() wrapper.

    Best regards,
    Kenneth

  • Unfortunaly i tried to modify the sdk library (nrfx_twi driver), it was almost working but the bytes i'm receiving don't look good.

    So i'm still looking for a solution.

  • 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 ...

Related