Nrf52840 one wire protocol usage with MAX17211 IC.

Hello Everyone,

                     I am trying to implement one wire protocol for interfacing MAX17211 fuel guage IC with NRF52840. I wand to know if there is any one wire library or any example which we can use to read the registers of MAX17211. Can we read the registers of MAX17211 directly from the data pin??Or we have to follow some particular signal pattern to read the data?

Thanks & Regards,

Snehal.

  • Hi,

    sne_333 said:
    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.

    What do you mean by not being able to read it properly? Are you getting the NRF_DRV_TWI_EVT_DONE event after you have called nrf_drv_twi_rx(), or are you getting a NRF_DRV_TWI_EVT_ADDRESS_NACK or NRF_DRV_TWI_EVT_DATA_NACK event?

    sne_333 said:
    unsigned conversion from 'int' to 'uint8_t' {aka 'unsigned char'} changes value from '437' to '181' [-Woverflow]

    Please show me where you are getting this warning.

  • I am getting warning as shown below:-

    #define NPACKCFG_REG     0x1B5

    when i try to read NPACKCFG_REG some conversion is happening.

    There are actually 2 slaves on the same i2c instance.

    I2c1_slave address = 0x6B

    I2c2_slave address = 0x6C

    I am able to communicate with slave 1 but when i try to communicate with slave 2 it gets hanged while sending data through nrf_drv_twi_tx in i2c_register_read_max17211 function.

    /*****************************************************************************
    * Copyright (c) [2021], Netobjex INC
    * All rights reserved.
    *
    * File:    task_psf_comm.c
    * Summary: PSF Control Task
    *
    */
    
    #include <stdint.h>
    #include <stdio.h>
    #include <string.h>
    
    #include "error_defs.h"
    
    #include "task_psf_comm.h"
    #include "FreeRTOS.h"
    #include "task.h"
    #include "semphr.h"
    #include "timers.h"
    
    #include "tasks.h"
    #include "boards.h"
    #include "nrf_gpio.h"
    #include "nrf_drv_gpiote.h"
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    #include "main.h"
    #include "task_led_button.h"
    
    #include "product_config.h"
    #include "nrf_drv_twi.h"
    #include "psf_i2c.h"
    #include "bq24292i.h"
    #include "max17211_i2c.h"
    
    
    /* I2C SLAVE 1*/
    #define BQ2429_ADDRESS_LEN  1         //BQ2429
    #define BQ2429_ADDRESS     (0xD6>>1)  //BQ2429 Device Address
    #define BQ2429_WHO_AM_I     0x6BU     //BQ2429 ID
    
    /* I2C SLAVE 2*/
    #define MAX17201_ADDRESS_LEN  1         
    #define MAX17201_ADDR     (0xD8>>1) //(0xD8>>1)  
    #define MAX17201_WHO_AM_I   0x6CU   
    
    #define TWI_INSTANCE_ID     0 //snehal
    
    
    
    
    /* TWI instance. */
    static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);
    static volatile bool m_xfer_done = false;
    
    //Event Handler
    void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
    {
        //Check the event to see what type of event occurred
        switch (p_event->type)
        {
            //If data transmission or receiving is finished
    	case NRF_DRV_TWI_EVT_DONE:
            m_xfer_done = true;//Set the flag
            break;
            
            default:
            // do nothing
              break;
        }
    }
    
    void twi_init (void)
    {
        ret_code_t err_code;
    
        const nrf_drv_twi_config_t twi_config = {
           .scl                = PSF_SCL_PIN,
           .sda                = PSF_SDA_PIN,
           .frequency          = NRF_DRV_TWI_FREQ_400K, 
           .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
           .clear_bus_init     = false
        };
    
        err_code = nrf_drv_twi_init(&m_twi, &twi_config, twi_handler, NULL);
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_twi_enable(&m_twi);
    }
    
    
    
    bool bq2429i_i2c_init(void)
    {
        ret_code_t err_code;
        uint8_t address = 0x6B;  
        uint8_t sample_data = 0x00;
    
        err_code = nrf_drv_twi_rx(&m_twi,address,&sample_data,sizeof(sample_data));
        if(err_code == NRF_SUCCESS)
        {
           NRF_LOG_INFO("SUCCESS");
           return true;
        }
        else
        {
           NRF_LOG_INFO("FAILED");
           return false;
        }
    
    }
    
    
    bool max17211_i2c_init(void)
    {
        ret_code_t err_code;
        uint8_t address = 0x6C;  
        uint8_t sample_data = 0x00;
    
        err_code = nrf_drv_twi_rx(&m_twi,address,&sample_data,sizeof(sample_data));
        if(err_code == NRF_SUCCESS)
        {
           NRF_LOG_INFO("SUCCESS");
           return true;
        }
        else
        {
           NRF_LOG_INFO("FAILED");
           return false;
        }
    
    }
    
    
    /*
      A Function to read data from the MPU6050
    */ 
    bool i2c_register_read(uint8_t register_address, uint8_t * destination, uint8_t number_of_bytes)
    {
        ret_code_t err_code;
    
        //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, BQ2429_ADDRESS, &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, BQ2429_ADDRESS, destination, number_of_bytes);
    		
        //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;
    }
    
    /*
       A function to write a Single Byte to MPU6050's internal Register
    */ 
    bool i2c_register_write(uint8_t register_address, uint8_t value)
    {
        ret_code_t err_code;
        uint8_t tx_buf[BQ2429_ADDRESS_LEN+1];
    	
        //Write the register address and data into transmit buffer
        tx_buf[0] = register_address;
        tx_buf[1] = value;
    
        //Set the flag to false to show the transmission is not yet completed
        m_xfer_done = false;
        
        //Transmit the data over TWI Bus
        err_code = nrf_drv_twi_tx(&m_twi, BQ2429_ADDRESS, tx_buf, BQ2429_ADDRESS_LEN+1, 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_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)
        {  }
        //vTaskDelay(1000);
    
       // 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)
    {
       // uint8_t address = 0x6C;  
    
        ret_code_t err_code;
    
        //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){}
    
        // 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, MAX17211_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){}
    
    
        // 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;
    
    }
    
    

    With slave 1 i have no issues reading and writing the data.

    What might be the issue that I am not getting m_xfer_done= true after sending data to the 2nd slave?? 

  • Vidar Berg said:
    are you getting a NRF_DRV_TWI_EVT_ADDRESS_NACK or NRF_DRV_TWI_EVT_DATA_NACK event?

    You are only handling the NRF_DRV_TWI_EVT_DONE event in your twi_handler(), and ignoring NRF_DRV_TWI_EVT_ADDRESS_NACK and NRF_DRV_TWI_EVT_DATA_NACK. Please add these events to your handler and see if either of these are triggered.

    Your screenshot does not show the source file from where you are getting the "unsigned conversion from 'int' to 'uint8_t' {aka 'unsigned char'} changes value from '437' to '181' [-Woverflow]" warning from.

Related