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.

Parents
  • Hello Edvin and thank you for your reply,

    indeed, the voltage drops that we were thinking about are not relevant, measured it on the current wiring setup, so far so good.

    Tested the address with the TWI Scanner example and got : 

    <info> app: TWI scanner started.
    <info> app: TWI device detected at address 0x60.

    Apparently, the sensor is found ok, btw please remind me where is the address on the TWI specifically defined? I want to check that in my application...

    I have easily copied the code from the TWI scanner into my application and interesting things pop out, not sure, if this is ok?

    TWI scanner started.<info> app: TWI scanner started.
    error code :    nothing?TWI device detected at address 0x1.<info> app: TWI device detected at address 0x1.
    TWI device detected at address 0x2.<info> app: TWI device detected at address 0x2.
    TWI device detected at address 0x3.<info> app: TWI device detected at address 0x3.
    TWI device detected at address 0x4.<info> app: TWI device detected at address 0x4.
    TWI device detected at address 0x5.<info> app: TWI device detected at address 0x5.
    TWI device detected at address 0x6.<info> app: TWI device detected at address 0x6.
    <info> app: TWI device detected at address 0x7.
    TWI device detected at address 0x8.TWI device detected at address 0x9.<info> app: TWI device detected at address 0x1C.
    TWI device detected at address 0x1d.<info> app: TWI device detected at address 0x1D.
    TWI device detected at address 0x1e.<info> app: TWI device detected at address 0x1E.
    TWI device detected at address 0x1f.<info> app: TWI device detected at address 0x1F.
    TWI device detected at address 0x20.<info> app: TWI device detected at address 0x20.
    TWI device detected at address 0x21.TWI device detected at address 0x22.TWI device detected at address 0x33.<info> app: TWI device detected at address 0x33.
    TWI device detected at address 0x34.<info> app: TWI device detected at address 0x34.
    TWI device detected at address 0x35.<info> app: TWI device detected at address 0x35.
    TWI device detected at address 0x36.<info> app: TWI device detected at address 0x36.
    TWI device detected at address 0x37.<info> app: TWI device detected at address 0x37.
    TWI device detected at address 0x38.TWI device detected at address 0x40.<info> app: TWI device detected at address 0x40.
    TWI device detected at address 0x41.<info> app: TWI device detected at address 0x41.
    TWI device detected at address 0x42.<info> app: TWI device detected at address 0x42.
    TWI device detected at address 0x43.TWI device detected at address 0x44.TWI device detected at address 0x50.<info> app: TWI device detected at address 0x50.
    TWI device detected at address 0x51.<info> app: TWI device detected at address 0x51.
    TWI device detected at address 0x52.<info> app: TWI device detected at address 0x52.
    TWI device detected at address 0x53.<info> app: TWI device detected at address 0x53.
    TWI device detected at address 0x54.<info> app: TWI device detected at address 0x6B.
    TWI device detected at address 0x6c.<info> app: TWI device detected at address 0x6C.
    TWI device detected at address 0x6d.<info> app: TWI device detected at address 0x6D.
    TWI device detected at address 0x6e.<info> app: TWI device detected at address 0x6E.
    TWI device detected at address 0x6f.<info> app: TWI device detected at address 0x6F.
    TWI device detected at address 0x70.<info> app: TWI device detected at address 0x70.
    <info> app: TWI device detected at address 0x76.
    TWI device detected at address 0x77.<info> app: TWI device detected at address 0x77.
    TWI device detected at address 0x78.<info> app: TWI device detected at address 0x78.
    TWI device detected at address 0x79.<info> app: TWI device detected at address 0x79.

    Best.

  • This is not the unmodified twi_scanner sample, right? It looks like it is finding a device on every address, which I assume is not actually the case. What does your application look like?

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

Reply
  • "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?

Children
  • MuRa said:
    I guess this was the aim of this code?

    Yes. My point is that the transfer call will return NRF_SUCCESS on all addresses if you have a TWI event handler. It just means that the packet was "successfully queued". 

  • Thanks Edvin, good to know what is the point of the event handler... can this be as well used on the "no_stop" parameter? See below for more.

    Anyway, now it is known that the access to the sensor , namely its slave address is correct , so this is not the problem while reading the sensor. For example, I am still getting strange output, for more see my previous post https://devzone.nordicsemi.com/f/nordic-q-a/84978/twi-reading-and-writing-basics/363652#363652

    There was a mention ( https://devzone.nordicsemi.com/f/nordic-q-a/84978/twi-reading-and-writing-basics/363652#363652 )  that "no_stop" could be a question for that problem, however, I did not checked that, because I am not sure what and how should be "no_stop" used, afterwards checked, if this is the issue at all. Looked for the explanation in the SDK, but could not find it. Can you help me in this case too, namely how to check, if my "no_stop" is the subject of concern for the strange output of the sensor ? Indeed, when the sensor is connected to the other dev platform, for which I have the manufacturers i2c API works seamlessly, the same sensor. 

    Looking forward to your reply.

  • I don't know what your sensor expects with regards to the stop contidition. Did you test both enabling and disabling it?

    Search for "stop condition" and "repeated start" in the datasheet for your sensor.

    It may also be, if you are using an event handler, and hence non-blocking TWI, that you are sending the messages too fast. Perhaps you should try to wait for the previous transaction to complete (and you get the callback) before you send the next message?

    Use the NRF_DRV_TWI_EVT_DONE event to set a parameter, and wait for this parameter to be set before sending the next message.

    Best regards,

    Edvin

Related