The TWI problems continue ...

Hello all,

for the last few weeks I am trying to workout the i2c protocol with the sensor and the nrf52dk , so far none of the solution that I have considered work. More can be seen here: https://devzone.nordicsemi.com/f/nordic-q-a/84978/twi-reading-and-writing-basics/363652#363652

I am thinking can the speed of the processor be too fast for the sensor prototype, like the wires to the board may be too long, for example, for example, the same prototype works on the Arduino's Atmel omega just ok... 

Therefore, to test this out my question is, how to reduce the speed of the i2c to less than 100kHz and how to reduce the speed of the processor? Indeed, if you have other suggestions please do not hesitate.

Thank you in advance, looking forward to your suggestions, ideas, how to tackle this further.

Best.

  • Hello, I guess it does, otherwise the address would not even be printed? See the code below.

    int main(void) {
    
      // search for sensor address
      if (true) {
    
        counter = 0;
        printf("Scanning for the sensor address \r\n");
        nrf_delay_ms(1000);
    
        ret_code_t err_code;
        uint8_t address;
        uint8_t sample_data;
        bool detected_device = false;
    
        printf("TWI scanner started.\r\n");
        nrf_delay_ms(1000);
      
        printf("initializing the twi !\r\n ");
    
        twi_init();
    
        nrf_delay_ms(500);
    
        for (address = 1; address <= TWI_ADDRESSES; address++) {
    
          err_code = nrf_drv_twi_rx(&m_twi, address, &sample_data, sizeof(sample_data));
         
            //nrf_delay_ms(100);
            //printf("nrf_sucess ", NRF_SUCCESS);
            //nrf_delay_ms(100);
    
          if (err_code == NRF_SUCCESS) {
            
            detected_device = true;
            printf("TWI device detected at address 0x%x. \r\n", address);
          }
               
        }
    
        if (!detected_device) {
          printf("No device was found. \r\n");
    
        }
    
        nrf_delay_ms(2000);
      }
    
      
    
      while (true) {
     
        printf("nothing in while loop \r\n");
       
        //nothing here
    
      }
    }

    Here is the output:

    initializing the twi !
    TWI device detected at address 0x1. 
    TWI device detected at address 0x10. 
    TWI device detected at address 0x1f. 
    TWI device detected at address 0x2d. 
    TWI device detected at address 0x3b. 
    TWI device detected at address 0x49. 
    TWI device detected at address 0x58. 
    TWI device detected at address 0x66. 
    TWI device detected at address 0x74. 
    nothing in while loop 

    Best.

    PS I have found the slave address that is used within the sensor library, api, code ...

  • Can I see your TWI init? Does your twi have an event handler? If it does, then the nrf_drv_twi_rx will return NRF_SUCCESS, and then later it should trigger the callback. If so, you will need to check the event handler, and not the return value of nrf_drv_twi_rx() to see whether anyone responded to that address.

    BR,

    Edvin

  • void twi_init(void) {
      ret_code_t err_code;
    
      const nrf_drv_twi_config_t twi_config = {
          .scl = 26, // Add you SCL Pin Here
          .sda = 27, // Add you SDA Pin Here
          .frequency = NRF_DRV_TWI_FREQ_100K,
          .interrupt_priority = APP_IRQ_PRIORITY_HIGHEST,
          .clear_bus_init = false};
    
      err_code = nrf_drv_twi_init(&m_twi, &twi_config, twi_handler, NULL);
    
      printf("error code :    ", err_code);
      nrf_delay_ms(550);
    
      printf("nothing ? \r\n");
      nrf_delay_ms(550);
    
      APP_ERROR_CHECK(err_code);
    
      nrf_delay_ms(550);
    
      nrf_drv_twi_enable(&m_twi);
    }

    There we go!
    BEST.

  • Edvin said:
    Does your twi have an event handler? If it does, then the nrf_drv_twi_rx will return NRF_SUCCESS, and then later it should trigger the callback.

    So because your TWI has an event handler (twi_handler), it means that all (most) calls to nrf_drv_twi_rx() will return NRF_SUCCESS, which means that the TWI successfully queued the operation. Do you get any callbacks in your twi_handler? What sort of events do you get?

    I guess you should look for the NRF_DRV_TWI_EVT_DONE, and check the address for those events. Something like:

    static void twi_handler(nrf_drv_twi_evt_t const * p_event,void * p_context)
    {
        switch(p_event->type)
        {
            case NRF_DRV_TWI_EVT_DONE:
                NRF_LOG_INFO("transfer success on addr 0x%02x", p_event->xfer_desc.address);
                break;
            case NRF_DRV_TWI_EVT_ADDRESS_NACK:
                NRF_LOG_INFO("Address nack on addr 0x%02x", p_event->xfer_desc.address);
                break;
            case NRF_DRV_TWI_EVT_DATA_NACK:
                NRF_LOG_INFO("Data nack on addr 0x%02x", p_event->xfer_desc.address);
                break;
            default
                break;
    }

  • "My" event handler:

    void twi_handler(nrf_drv_twi_evt_t const *p_event, void *p_context) {
      switch (p_event->type) {
      case NRF_DRV_TWI_EVT_DONE:
        if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_RX) {
        }
        m_xfer_done = true;
        break;
      default:
        break;
      }
    }

    "Your" event handler, btw different printing used:

    static void twi_handler(nrf_drv_twi_evt_t const *p_event, void *p_context) {
      switch (p_event->type) {
      case NRF_DRV_TWI_EVT_DONE:
        printf("transfer success on addr 0x%02x \n", p_event->xfer_desc.address);
        //NRF_LOG_INFO("transfer success on addr 0x%02x", p_event->xfer_desc.address);
        break;
      case NRF_DRV_TWI_EVT_ADDRESS_NACK:
      printf("transfer success on addr 0x%02x \n", p_event->xfer_desc.address);
        //NRF_LOG_INFO("Address nack on addr 0x%02x", p_event->xfer_desc.address);
        break;
      case NRF_DRV_TWI_EVT_DATA_NACK:
      printf("Data nack on addr 0x%02x \n", p_event->xfer_desc.address);
        //NRF_LOG_INFO("Data nack on addr 0x%02x", p_event->xfer_desc.address);
        break;
      default:
        break;
      }
    }

    it finds the sensor slave address, "transfer success on addr 0x60 "

    I guess this was the aim of this code?

Related