Read data from 16bit register TWI on NRF52833.

Hi All, 

         I am trying to communicate with IC MAX17201 using I2C interface. I am able to detect the IC and communicate with it. 

When I read 8bit registers from the IC I don't have any issue. But when I am trying to read 16bit register from the IC, I am getting errors.The existing code from NRF SDK includes data to read and write 8 bit registers.

I have modified the code a bit in order to read 2bytes from register. I am not able to read 16bit registers. I tried to read NPACKCFG_REG but not able to read it properly. As well as while compiling I am getting warnings like this:-unsigned conversion from 'int' to 'uint8_t' {aka 'unsigned char'} changes value from '437' to '181' [-

#define NPACKCFG_REG     0x1B5

#define MAX17201_ADDRESS_LEN  1         
#define MAX17201_ADDR     (0xD8>>1)  
#define MAX17201_WHO_AM_I     0x6BU     

bool i2c_register_write_max17211(uint16_t register_address, uint16_t value)
{

      ret_code_t err_code;
      uint8_t tx_data[4];

      tx_data[0] = ( (register_address >> 8)& 0xFF );
      tx_data[1] = register_address & 0xFF;
      tx_data[2] = ((value>>8)& 0xff);
      tx_data[3] = value & 0xFF;

      m_xfer_done = false;
    
      err_code = nrf_drv_twi_tx(&m_twi, MAX17201_WHO_AM_I, tx_data, sizeof(tx_data), false);
  //Wait until the transmission of the data is finished
    while (m_xfer_done == false)
    {
      }

   // if there is no error then return true else return false
    if (NRF_SUCCESS != err_code)
    {
        NRF_LOG_INFO("FAILED");
        return false;
    }

    NRF_LOG_INFO("SUCCESS");

    return true;	

}

bool i2c_register_read_max17211(uint8_t register_address, uint8_t destination[2], uint8_t number_of_bytes)
{
    ret_code_t err_code;
    //uint8_t rx_buffer[2];

    //Set the flag to false to show the receiving is not yet completed
    m_xfer_done = false;
    
    // Send the Register address where we want to write the data
    err_code = nrf_drv_twi_tx(&m_twi, MAX17201_WHO_AM_I, &register_address, 1, true);
	  
    //Wait for the transmission to get completed
    while (m_xfer_done == false){}
    //vTaskDelay(1000);

    // If transmission was not successful, exit the function with false as return value
    if (NRF_SUCCESS != err_code)
    {
        return false;
    }

    //set the flag again so that we can read data from the MPU6050's internal register
    m_xfer_done = false;
	  
    // Receive the data from the MPU6050
    //err_code = nrf_drv_twi_rx(&m_twi, MAX17201_WHO_AM_I, destination, number_of_bytes);
    err_code = nrf_drv_twi_rx(&m_twi, MAX17201_WHO_AM_I, &destination[0], sizeof(destination));
		
    //wait until the transmission is completed
    while (m_xfer_done == false){}
    //vTaskDelay(1000);


    // if data was successfully read, return true else return false
    if (NRF_SUCCESS != err_code)
    {
        return false;
    }
    
    //NRF_LOG_INFO("DATA IS %x",destination);
    return true;

}

Please help me on how to read multiple bytes from 16bit registers and how to write data into 16 bit registers.

Parents
  • Hi,

    Your code looks correct to me, given that the MAX17201 expects the 16-bit register address in this format. What is the problem when reading/writing this register? "not able to read it properly" does not provide much information about what goes wrong.

    Have you checked the TWI lines with a logic analyzer, to see if the expected register address is output, and it the sensor outputs any of the expected data?

    The warning is expected when assigning the value of a 16-bit variable into 8-bit variable without a cast. As long as this is the expected behavior, you can ignore the warning and/or cast the 16-bit variable to uint8_t when assigning.

    Best regards,
    Jørgen

  • yes we checked the lines, there was problem with the slave ID. Now I am able to communicate properly. The code which I shared above for reading register is for reading 8 bit register. How can I modify it to read 16bit registers??

    existing code is as follows:-

    bool i2c_register_read_max17211(uint8_t register_address, uint8_t destination[2], uint8_t number_of_bytes)
    {
        ret_code_t err_code;
        //uint8_t rx_buffer[2];
    
        //Set the flag to false to show the receiving is not yet completed
        m_xfer_done = false;
        
        // Send the Register address where we want to write the data
        err_code = nrf_drv_twi_tx(&m_twi, MAX17201_WHO_AM_I, &register_address, 1, true);
    	  
        //Wait for the transmission to get completed
        while (m_xfer_done == false){}
        //vTaskDelay(1000);
    
        // If transmission was not successful, exit the function with false as return value
        if (NRF_SUCCESS != err_code)
        {
            return false;
        }
    
        //set the flag again so that we can read data from the MPU6050's internal register
        m_xfer_done = false;
    	  
        // Receive the data from the MPU6050
        //err_code = nrf_drv_twi_rx(&m_twi, MAX17201_WHO_AM_I, destination, number_of_bytes);
        err_code = nrf_drv_twi_rx(&m_twi, MAX17201_WHO_AM_I, &destination[0], sizeof(destination));
    		
        //wait until the transmission is completed
        while (m_xfer_done == false){}
        //vTaskDelay(1000);
    
    
        // if data was successfully read, return true else return false
        if (NRF_SUCCESS != err_code)
        {
            return false;
        }
        
        //NRF_LOG_INFO("DATA IS %x",destination);
        return true;
    
    }

Reply
  • yes we checked the lines, there was problem with the slave ID. Now I am able to communicate properly. The code which I shared above for reading register is for reading 8 bit register. How can I modify it to read 16bit registers??

    existing code is as follows:-

    bool i2c_register_read_max17211(uint8_t register_address, uint8_t destination[2], uint8_t number_of_bytes)
    {
        ret_code_t err_code;
        //uint8_t rx_buffer[2];
    
        //Set the flag to false to show the receiving is not yet completed
        m_xfer_done = false;
        
        // Send the Register address where we want to write the data
        err_code = nrf_drv_twi_tx(&m_twi, MAX17201_WHO_AM_I, &register_address, 1, true);
    	  
        //Wait for the transmission to get completed
        while (m_xfer_done == false){}
        //vTaskDelay(1000);
    
        // If transmission was not successful, exit the function with false as return value
        if (NRF_SUCCESS != err_code)
        {
            return false;
        }
    
        //set the flag again so that we can read data from the MPU6050's internal register
        m_xfer_done = false;
    	  
        // Receive the data from the MPU6050
        //err_code = nrf_drv_twi_rx(&m_twi, MAX17201_WHO_AM_I, destination, number_of_bytes);
        err_code = nrf_drv_twi_rx(&m_twi, MAX17201_WHO_AM_I, &destination[0], sizeof(destination));
    		
        //wait until the transmission is completed
        while (m_xfer_done == false){}
        //vTaskDelay(1000);
    
    
        // if data was successfully read, return true else return false
        if (NRF_SUCCESS != err_code)
        {
            return false;
        }
        
        //NRF_LOG_INFO("DATA IS %x",destination);
        return true;
    
    }

Children
No Data
Related