This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

twi_scanner for nRF52840DK + nRF Connect SDK

Hello!

I have a nRF52840DK with a custom board. I have installed nRF 1.9.1. I have read about the twi_scanner but I don't find that code in my installation! Did I do anything wrong? How can I develop a twi_scanner for my nRF Connect environment?

Regards,

David.

Parents
  • Hi there!

    Moving forward, I have compiled a version that seems to work (initially). However, I get stuck:

    - I execute a successful nrfx_twim_xfer(&i2c_instance, &xdesc, 0)

    - My evt_handler doesn't get invoked

    nrfx_twim_is_busy(&i2c_instance) is always true

    So i cannot invoke nrfx_twim_xfer any more.

    As this is a twim_scanner it is very likely that the address I'm polling doesn't belong to any device (so nobody will never reply), so, my questions:

    1. If I poll an address with no device, will the library stay on busy forever?

    2. Is there a way to check for a timeout, clear the busy state and run more transfers?

    Regards,

    David.

Reply
  • Hi there!

    Moving forward, I have compiled a version that seems to work (initially). However, I get stuck:

    - I execute a successful nrfx_twim_xfer(&i2c_instance, &xdesc, 0)

    - My evt_handler doesn't get invoked

    nrfx_twim_is_busy(&i2c_instance) is always true

    So i cannot invoke nrfx_twim_xfer any more.

    As this is a twim_scanner it is very likely that the address I'm polling doesn't belong to any device (so nobody will never reply), so, my questions:

    1. If I poll an address with no device, will the library stay on busy forever?

    2. Is there a way to check for a timeout, clear the busy state and run more transfers?

    Regards,

    David.

Children
  • This is my main function, just in case it could help:

    int main(void)
    {
        nrfx_err_t err;
        uint8_t address;
        uint8_t data_tx[1] = {0};
        uint8_t data_rx[8];
        int blink_status = 0;
        void *context = NULL;
        nrfx_twim_xfer_desc_t xdesc;

        k_sleep (K_SECONDS (5));

        const nrfx_twim_t i2c_instance = NRFX_TWIM_INSTANCE(0);
        const nrfx_twim_config_t i2c_config = NRFX_TWIM_DEFAULT_CONFIG (41, 8);
        err = nrfx_twim_init (&i2c_instance, &i2c_config, evt_handler, context);
        nrfx_twim_enable (&i2c_instance);

        k_sleep (K_SECONDS (5));

        xdesc.type = NRFX_TWIM_XFER_TXRX;
        xdesc.primary_length = 1;
        xdesc.secondary_length = 1;
        xdesc.p_primary_buf = (data_tx);
        xdesc.p_secondary_buf = (data_rx);
        while (true)
        {
            for (address = 0; address <= 127; address++)
            {
                while (nrfx_twim_is_busy(&i2c_instance)) {
                    k_sleep(K_MSEC(1000));            
                    LOG_INF("Busy");
                }

                xdesc.address = address;
                nrfx_err_t err = nrfx_twim_xfer(&i2c_instance, &xdesc, 0);
           
                switch (err) {
                    case NRFX_SUCCESS: // The procedure is successful.
                        LOG_INF("Parece que alguien responde en %d", address);
                    break;
                    case NRFX_ERROR_BUSY: // The driver is not ready for a new transfer.
                        LOG_INF("The driver is not ready for a new transfer");
                    break;
                    case NRFX_ERROR_NOT_SUPPORTED: // The provided parameters are not supported.
                        LOG_INF("The provided parameters are not supported");
                    break;
                    case NRFX_ERROR_INTERNAL: // An unexpected transition occurred on the bus.
                        LOG_INF("An unexpected transition occurred on the bus");
                    break;
                    case NRFX_ERROR_INVALID_ADDR: // The provided buffers are not placed in the Data RAM region.
                        LOG_INF("The provided buffers are not placed in the Data RAM region");
                    break;
                    case NRFX_ERROR_DRV_TWI_ERR_OVERRUN: // The unread data is replaced by new data.
                        LOG_INF("The unread data is replaced by new data");
                    break;
                    case NRFX_ERROR_DRV_TWI_ERR_ANACK: // NACK is received after sending the address.
                        LOG_INF("NACK is received after sending the address");
                    break;
                    case NRFX_ERROR_DRV_TWI_ERR_DNACK: // NACK is received after sending a data byte.
                        LOG_INF("NACK is received after sending a data byte");
                    break;
                    default:
                        LOG_INF("Error en nrfx_twim_xfer %d", err);
                }
        }
    }
    Regards,
    David.
  • Hi,

    Have you remembered to enable the interrupts by calling IRQ_DIRECT_CONNECT() and irq_enable() in your init routine?

    Something like this:

    	IRQ_DIRECT_CONNECT(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQn, 0, nrfx_twim_0_irq_handler, 0);
    	irq_enable(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQn);

    The callback handler won't be invoked if this hasn't been done already.

    regards

    Jared 

  • Hi Jared:

    No, I didn't know it. I will try later and come back here.

    Thank you,

    David.

  • Thank you Jared, it worked; my event handler is now being invoked and the device is not busy any more.

    Best regards,

    David.

Related