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

Read and Write TWI Sensor Registers

Hi there,

I'm developing with the nRF52840 right now.

I'm trying to read some sensordata with TWI. The sensors are BMM150, BMI270 and BMP388.

Unfortunately, I already have problems with the my first sensor (BMM150), reading the Chip ID.

To read it, I have to set the Power Control Bit of the sensor. That seems to be working.

But when I want to read registers again, I only get zeros. Even for reading the Power Control Bit.


This is the function to write Registers:

bool writeRegister(uint8_t regNumber, uint8_t value){
  ret_code_t err_code;

  uint8_t valueBuffer[2];
  valueBuffer[0] = regNumber;
  valueBuffer[1] = value;
  err_code = nrf_drv_twi_tx(&m_twi, 0x10, valueBuffer, sizeof(valueBuffer), false);
  APP_ERROR_CHECK(err_code);
  return 1;
}


Read Registers:

uint8_t readRegister(uint8_t regNumber){
  ret_code_t err_code;

  uint8_t resultsWhoAmI;
  uint8_t whoAmIPointer = regNumber;
  err_code = nrf_drv_twi_tx(&m_twi, 0x10, &whoAmIPointer, 1, true);
  err_code = nrf_drv_twi_rx(&m_twi, 0x10, &resultsWhoAmI, 1);
  APP_ERROR_CHECK(err_code);

  return resultsWhoAmI;
}



Main to test reading the Chip ID. Later on I want to use the Bosch Sensortec API. But first I want this one to work:
int main(void)
{
    ret_code_t err_code;
    uint8_t address = 0x10;
    uint8_t read_data;
    uint8_t write_data;

 
    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();

    NRF_LOG_INFO("Read Chip ID started");

    NRF_LOG_FLUSH();
    twi_init();

    // Read Power Control Bit
    read_data = readRegister(0x4B);
    uint8_t pwr_bit = read_data & 0b1;
    NRF_LOG_INFO("Read Power Control = %x", pwr_bit);
    NRF_LOG_FLUSH();

    write_data = read_data | 1;
    writeRegister(0x4B, write_data);
    NRF_LOG_INFO("Set Power Control Register to %x", write_data & 0b1);
    NRF_LOG_FLUSH();

    read_data = readRegister(0x4B);
    pwr_bit = read_data & 0b1;
    NRF_LOG_INFO("Read Power Control = %x", pwr_bit);
    NRF_LOG_FLUSH();


    read_data = readRegister(0x4C);
    uint8_t opMode = (read_data | 0b110) >> 1;
    NRF_LOG_INFO("Read MODE = %x", opMode);
    NRF_LOG_FLUSH();

    write_data = read_data | 0b00000110;
    writeRegister(0x4b, write_data);
    NRF_LOG_INFO("Set Mode Register to: %x", (write_data & 0b110)>>1);
    NRF_LOG_FLUSH();

    read_data = readRegister(0x4C);
    opMode = (read_data | 0b110) >> 1;
    NRF_LOG_INFO("Read MODE = %x", opMode);
    NRF_LOG_FLUSH();

    nrf_delay_ms(5000);

    read_data = readRegister(0x4B);
    pwr_bit = read_data & 0b1;
    NRF_LOG_INFO("Read Power Control = %x", pwr_bit);
    NRF_LOG_FLUSH();

    read_data = readRegister(0x40);
    NRF_LOG_INFO("Chip ID = %x", read_data);
    NRF_LOG_FLUSH();

}



This is the Output:

I've already read a couple of posts where others also had trouble reading on the bus after something was written. However, I couldn't find a solution.

Maybe somethings wrong with my code. I hope you could help me.


Thank you.







Parents
  • I just created a minimal example to reproduce the issue.

    I used the bmm150.

    In the first write operation I set the power control bit to 1 (has to be done to read the chip id). 

    When I just do this WRITE Operation the reading of the chip ID works fine.

    But if I write the mode register beforehand (without changing anything), the reading of the Chip ID doesn't work anymore.

    I hope this helps to reproduce the issue

    #include <stdio.h>
    #include "boards.h"
    #include "app_util_platform.h"
    #include "app_error.h"
    #include "nrf_delay.h"
    
    // include I2C Lib
    #include "nrf_drv_twi.h"
    
    // include LOG Libs
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    
    /* TWI instance ID. */
    #define TWI_INSTANCE_ID     0
    
    /* TWI instance. */
    static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);
    
    
    /**
     * @brief TWI initialization.
     */
    void twi_init (void)
    {
        ret_code_t err_code;
    
        const nrf_drv_twi_config_t twi_config = {
           .scl                = SCL0_PIN,
           .sda                = SDA0_PIN,
           .frequency          = NRF_DRV_TWI_FREQ_100K,
           .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
           .clear_bus_init     = true
        };
    
        err_code = nrf_drv_twi_init(&m_twi, &twi_config, NULL, NULL);
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_twi_enable(&m_twi);
    }
    
    bool writeRegister(uint8_t regNumber, uint8_t value){
      ret_code_t err_code;
    
      uint8_t valueBuffer[2];
      valueBuffer[0] = regNumber;
      valueBuffer[1] = value;
      err_code = nrf_drv_twi_tx(&m_twi, 0x10, valueBuffer, sizeof(valueBuffer), false);
      APP_ERROR_CHECK(err_code);
      return 1;
    }
    
    uint8_t readRegister(uint8_t regNumber){
      ret_code_t err_code;
    
      uint8_t resultsWhoAmI;
      uint8_t whoAmIPointer = regNumber;
      err_code = nrf_drv_twi_tx(&m_twi, 0x10, &whoAmIPointer, 1, false);
      err_code = nrf_drv_twi_rx(&m_twi, 0x10, &resultsWhoAmI, 1);
      APP_ERROR_CHECK(err_code);
    
      return resultsWhoAmI;
    }
    
    
    /**
     * @brief Function for main application entry.
     */
    int main(void)
    {
        ret_code_t err_code;
        uint8_t address = 0x10;
        uint8_t read_data;
        uint8_t write_data;
        
        nrf_delay_ms(00);
     
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    
        NRF_LOG_INFO("Read Chip ID started");
    
        NRF_LOG_FLUSH();
        twi_init();
    
        nrf_delay_ms(500);
    
        // Read Power Control Bit
        read_data = readRegister(0x4B);
        uint8_t pwr_bit = read_data & 0b1;
        NRF_LOG_INFO("Read Power Control = %x", read_data);
        NRF_LOG_FLUSH();
    
        write_data = read_data | 1;
        writeRegister(0x4B, write_data);
        NRF_LOG_INFO("Set Power Control Register to %x", write_data & 0b1);
        NRF_LOG_FLUSH();
    
        read_data = readRegister(0x4B);
        pwr_bit = read_data & 0b1;
        NRF_LOG_INFO("Read Power Control = %x", pwr_bit);
        NRF_LOG_FLUSH();
    
    
        read_data = readRegister(0x4C);
        uint8_t opMode = (read_data | 0b110) >> 1;
        NRF_LOG_INFO("Read MODE = %x", opMode);
        NRF_LOG_FLUSH();
    
        write_data = read_data | 0b00000110;
        writeRegister(0x4b, write_data);
        NRF_LOG_INFO("Set Mode Register to: %x", (write_data & 0b110)>>1);
        NRF_LOG_FLUSH();
    
    
        while(1){
          nrf_delay_ms(500);
          read_data = readRegister(0x4B);
          pwr_bit = read_data & 0b1;
          NRF_LOG_INFO("Read Power Control = %x", pwr_bit);
          NRF_LOG_FLUSH();
    
          read_data = readRegister(0x40);
          NRF_LOG_INFO("Chip ID = %x", read_data);
          NRF_LOG_FLUSH();
       }
    }

Reply
  • I just created a minimal example to reproduce the issue.

    I used the bmm150.

    In the first write operation I set the power control bit to 1 (has to be done to read the chip id). 

    When I just do this WRITE Operation the reading of the chip ID works fine.

    But if I write the mode register beforehand (without changing anything), the reading of the Chip ID doesn't work anymore.

    I hope this helps to reproduce the issue

    #include <stdio.h>
    #include "boards.h"
    #include "app_util_platform.h"
    #include "app_error.h"
    #include "nrf_delay.h"
    
    // include I2C Lib
    #include "nrf_drv_twi.h"
    
    // include LOG Libs
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    
    /* TWI instance ID. */
    #define TWI_INSTANCE_ID     0
    
    /* TWI instance. */
    static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);
    
    
    /**
     * @brief TWI initialization.
     */
    void twi_init (void)
    {
        ret_code_t err_code;
    
        const nrf_drv_twi_config_t twi_config = {
           .scl                = SCL0_PIN,
           .sda                = SDA0_PIN,
           .frequency          = NRF_DRV_TWI_FREQ_100K,
           .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
           .clear_bus_init     = true
        };
    
        err_code = nrf_drv_twi_init(&m_twi, &twi_config, NULL, NULL);
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_twi_enable(&m_twi);
    }
    
    bool writeRegister(uint8_t regNumber, uint8_t value){
      ret_code_t err_code;
    
      uint8_t valueBuffer[2];
      valueBuffer[0] = regNumber;
      valueBuffer[1] = value;
      err_code = nrf_drv_twi_tx(&m_twi, 0x10, valueBuffer, sizeof(valueBuffer), false);
      APP_ERROR_CHECK(err_code);
      return 1;
    }
    
    uint8_t readRegister(uint8_t regNumber){
      ret_code_t err_code;
    
      uint8_t resultsWhoAmI;
      uint8_t whoAmIPointer = regNumber;
      err_code = nrf_drv_twi_tx(&m_twi, 0x10, &whoAmIPointer, 1, false);
      err_code = nrf_drv_twi_rx(&m_twi, 0x10, &resultsWhoAmI, 1);
      APP_ERROR_CHECK(err_code);
    
      return resultsWhoAmI;
    }
    
    
    /**
     * @brief Function for main application entry.
     */
    int main(void)
    {
        ret_code_t err_code;
        uint8_t address = 0x10;
        uint8_t read_data;
        uint8_t write_data;
        
        nrf_delay_ms(00);
     
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    
        NRF_LOG_INFO("Read Chip ID started");
    
        NRF_LOG_FLUSH();
        twi_init();
    
        nrf_delay_ms(500);
    
        // Read Power Control Bit
        read_data = readRegister(0x4B);
        uint8_t pwr_bit = read_data & 0b1;
        NRF_LOG_INFO("Read Power Control = %x", read_data);
        NRF_LOG_FLUSH();
    
        write_data = read_data | 1;
        writeRegister(0x4B, write_data);
        NRF_LOG_INFO("Set Power Control Register to %x", write_data & 0b1);
        NRF_LOG_FLUSH();
    
        read_data = readRegister(0x4B);
        pwr_bit = read_data & 0b1;
        NRF_LOG_INFO("Read Power Control = %x", pwr_bit);
        NRF_LOG_FLUSH();
    
    
        read_data = readRegister(0x4C);
        uint8_t opMode = (read_data | 0b110) >> 1;
        NRF_LOG_INFO("Read MODE = %x", opMode);
        NRF_LOG_FLUSH();
    
        write_data = read_data | 0b00000110;
        writeRegister(0x4b, write_data);
        NRF_LOG_INFO("Set Mode Register to: %x", (write_data & 0b110)>>1);
        NRF_LOG_FLUSH();
    
    
        while(1){
          nrf_delay_ms(500);
          read_data = readRegister(0x4B);
          pwr_bit = read_data & 0b1;
          NRF_LOG_INFO("Read Power Control = %x", pwr_bit);
          NRF_LOG_FLUSH();
    
          read_data = readRegister(0x40);
          NRF_LOG_INFO("Chip ID = %x", read_data);
          NRF_LOG_FLUSH();
       }
    }

Children
No Data
Related