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

AT24C512 + BMI160 + NRF52

Hi,

I am using nRF52832 soc to develop my project. with nRF5_SDK_15.3 . SES file

I need to connect both BMI160 accelerometer sensor and AT24C512 EEPROM ic in TWI.

how to use TWI with this. guide me to use both at a time.

BMI160 separately i can read the data.

but i can't read while connect to AT24C512

  • The application communicates over the two-wire interface (TWI) with two devices: the MMA7660 triple axis accelerometer and the LM75B temperature sensor.

    The example uses the RTC peripheral to generate regular tick events (32 per second). The interrupt handler, executed in reaction to each tick event, schedules data transfers to read the current values from the devices. The obtained values are averaged and printed every 500 milliseconds or when the tilting status reported by the accelerometer changes. Additionally, the user can generate asynchronous data transfer requests (reading all registers available in the devices) by pressing Button 1 or Button 4. Such additional transfer requests show that the TWI transaction manager library can schedule transfer requests from different contexts and realize them in the order they were scheduled.

  • the TWI transaction manager library can schedule transfer requests from different contexts and realize them in the order they were scheduled

    obviously, that adds a layer of complexity.

    The alternative is that you have to manage the bus accesses yourself in your own code so that the 2 sensors do not interfere with each other.

    If you have a simple use case, with only the 2 sensors, it may not be (too) difficult to manage this "manually"...

    But only you know the details of your application - so only you can decide what's appropriate to it.

  • HI,

    I have combined the code in a same TWI0 as

    void E_twi_init (void)
    {
        ret_code_t err_code;
    const nrf_drv_twi_config_t twi_e_config = {
           .scl                = ARDUINO_SCL_PIN,
           .sda                = ARDUINO_SDA_PIN,
           .frequency          = NRF_DRV_TWI_FREQ_100K,
           .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
           .clear_bus_init     = false
        };
    
        err_code = nrf_drv_twi_init(&m_twi, &twi_e_config, NULL, NULL);
        
        APP_ERROR_CHECK(err_code);
        if (NRF_SUCCESS == err_code)
    	{
    		nrf_drv_twi_enable(&m_twi);
    		NRF_LOG_INFO("EEPROM TWI init success...");	
    	}
    }

    / <e> TWI0_ENABLED - Enable TWI0 instance
    //==========================================================
    #ifndef TWI0_ENABLED
    #define TWI0_ENABLED 1
    #endif
    // <q> TWI0_USE_EASY_DMA  - Use EasyDMA (if present)
     
    
    #ifndef TWI0_USE_EASY_DMA
    #define TWI0_USE_EASY_DMA 1
    #endif
    
    // </e>
    
    // <e> TWI1_ENABLED - Enable TWI1 instance
    //==========================================================
    #ifndef TWI1_ENABLED
    #define TWI1_ENABLED 0
    #endif
    // <q> TWI1_USE_EASY_DMA  - Use EasyDMA (if present)

    can you check my code

    it is reliable ?!  (i.e - It work for long real time process)

    #include <stdio.h>
    #include "boards.h"
    #include "app_util_platform.h"
    #include "app_error.h"
    #include "nrf_drv_twi.h"
    #include "nrf_delay.h"
    
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    #include "bmi160.h"
    
    /* TWI instance ID. */
    #define TWI_INSTANCE_ID     0
    #define TWI1_INSTANCE_ID     1
    #define I2C_24C128_SLAVE_ADDR        (0x50)
    #define G_TO_LSB (16384.0f)
    
    #define DPS_TO_LSB (131.072f)
    
    /* Indicates if operation on TWI has ended. */
    static volatile bool m_xfer_done = false;
    
    /* TWI instance. */
    static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);
    //static const nrf_drv_twi_t m_twi_e = NRF_DRV_TWI_INSTANCE(TWI1_INSTANCE_ID);
    
    void eep_WriteByte(uint16_t eep_address, unsigned char val);
    unsigned char eep_readByte(uint16_t eep_address);
    ret_code_t err_codecpy;
    
    struct bmi160_dev sensor;
    struct bmi160_sensor_data accel;
    struct bmi160_sensor_data gyro;
    struct bmi160_int_settg int_config;
    
    int8_t rslt = BMI160_OK;
    
    
    
    void B_twi_init (void)
    {
        ret_code_t err_code;
    
        const nrf_drv_twi_config_t twi_config = {
           .scl                = ARDUINO_SCL_PIN,
           .sda                = ARDUINO_SDA_PIN,
           .frequency          = NRF_DRV_TWI_FREQ_100K,
           .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
           .clear_bus_init     = false
        };
    
        err_code = nrf_drv_twi_init(&m_twi, &twi_config, NULL, NULL);
        NRF_LOG_INFO("err_code :%d", err_code);
        APP_ERROR_CHECK(err_code);
        if (NRF_SUCCESS == err_code)
    	{
    		nrf_drv_twi_enable(&m_twi);
    		NRF_LOG_INFO("BMI TWI init success...");	
    	}
    }
    
    void E_twi_init (void)
    {
        ret_code_t err_code;
    const nrf_drv_twi_config_t twi_e_config = {
           .scl                = ARDUINO_SCL_PIN,
           .sda                = ARDUINO_SDA_PIN,
           .frequency          = NRF_DRV_TWI_FREQ_100K,
           .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
           .clear_bus_init     = false
        };
    
        err_code = nrf_drv_twi_init(&m_twi, &twi_e_config, NULL, NULL);
        
        APP_ERROR_CHECK(err_code);
        if (NRF_SUCCESS == err_code)
    	{
    		nrf_drv_twi_enable(&m_twi);
    		NRF_LOG_INFO("EEPROM TWI init success...");	
    	}
    }
    unsigned char eep_readByte(uint16_t eep_address)
    {
    
        unsigned char eep_by_address[2];
        unsigned char reg=0;
        eep_by_address[1]   = eep_address;
        eep_by_address[0] = (unsigned char)(eep_address << 8);
        // setting the start address
        nrf_drv_twi_tx(&m_twi, I2C_24C128_SLAVE_ADDR, eep_by_address, 2, true);
        // read a byte
        nrf_delay_ms(5);
    
        nrf_drv_twi_rx(&m_twi, I2C_24C128_SLAVE_ADDR, &reg,1);
    
        nrf_delay_ms(5);
    	return reg;
    }
    void eep_WriteByte(uint16_t eep_address, unsigned char val)
    {
    
        unsigned char eep_by_address[3];
        eep_by_address[2] = val;
        eep_by_address[1] = eep_address;
        eep_by_address[0] = (unsigned char)(eep_address << 8);
    
        err_codecpy = nrf_drv_twi_tx(&m_twi, I2C_24C128_SLAVE_ADDR, eep_by_address, 3, false);
        nrf_delay_ms(5);
        if(err_codecpy == 0)
        {
          NRF_LOG_INFO("\r\nWritten Sucess");
        NRF_LOG_FLUSH();
        }
    
    }
    
    
    
    int8_t Acc_i2c_Write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
    {
    
        //  NRF_LOG_INFO("WRITE: dev_id: %x reg_addr: %x reg_data: %x len: %i\n", dev_id, reg_addr, *reg_data, len);
    	int8_t rslt = 0;
    	uint8_t data[len + 1];
    	data[0] = reg_addr;
    	for (uint16_t i = 0; i < len; i++) {
    		data[i + 1] = reg_data[i];
    	}
    	
    	rslt = nrf_drv_twi_tx(&m_twi, dev_id, data, len + 1, false);
    	APP_ERROR_CHECK(rslt);
            return rslt;
      
    }
    
    
    int8_t Acc_i2c_Read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
    {
    	int8_t rslt = 0;
       //     NRF_LOG_INFO("READ: dev_id: %x reg_addr: %x len: %i\n", dev_id, reg_addr, len);
    	rslt = nrf_drv_twi_tx(&m_twi, dev_id, &reg_addr, 1, false);
            APP_ERROR_CHECK(rslt);
    
    	if (rslt == 0)
    	{
    		rslt = nrf_drv_twi_rx(&m_twi, dev_id, reg_data, len);
    	}
        //    NRF_LOG_INFO("READ: %x",*reg_data);
    	return rslt;
    }
    
    void Acc_delay_ms(uint32_t period)
    { 
      nrf_delay_ms( period ) ;
    }
    
    void BMI_init (void)
    {
        sensor.id = BMI160_I2C_ADDR;         //0x69
        sensor.interface = BMI160_I2C_INTF;  //0x00
        sensor.read = &Acc_i2c_Read;
        sensor.write = &Acc_i2c_Write;
        sensor.delay_ms = &Acc_delay_ms;
    
        rslt = bmi160_init(&sensor);
        APP_ERROR_CHECK(rslt);
    
        if(rslt == BMI160_OK){
        NRF_LOG_INFO("BMI160 Initialized...");
        } else {
        NRF_LOG_INFO("BMI160 not Initialized...");
        }NRF_LOG_FLUSH();
    
        sensor.accel_cfg.odr = BMI160_ACCEL_ODR_1600HZ;
        sensor.accel_cfg.range = BMI160_ACCEL_RANGE_2G;
        sensor.accel_cfg.bw = BMI160_ACCEL_BW_NORMAL_AVG4;
        sensor.accel_cfg.power = BMI160_ACCEL_NORMAL_MODE;
    
        sensor.gyro_cfg.odr = BMI160_GYRO_ODR_3200HZ;
        sensor.gyro_cfg.range = BMI160_GYRO_RANGE_2000_DPS;
        sensor.gyro_cfg.bw = BMI160_GYRO_BW_NORMAL_MODE;
        sensor.gyro_cfg.power = BMI160_GYRO_NORMAL_MODE;
    
        rslt = bmi160_set_sens_conf(&sensor);
        APP_ERROR_CHECK(rslt);
    
         if(rslt == BMI160_OK){
        NRF_LOG_INFO("sensor Configured...");
        } else {
        NRF_LOG_INFO("sensor not Configured...");
        }NRF_LOG_FLUSH();
    }
    /**
     * @brief Function for reading data from temperature sensor.
     */
    static void read_sensor_data()
    {
        m_xfer_done = false;
        unsigned char  reg1 = 0;
        bmi160_get_sensor_data((BMI160_ACCEL_SEL | BMI160_GYRO_SEL | BMI160_TIME_SEL), &accel, &gyro, &sensor);
        float accelX = ((((float)accel.x) / G_TO_LSB) * 9.80655); // in m/s^2
          float gyrX = ((((float)gyro.x) / DPS_TO_LSB) * 0.0174532925); // in rad/sec
          NRF_LOG_INFO("DataX in m/s^2   : " NRF_LOG_FLOAT_MARKER, 
          NRF_LOG_FLOAT( accelX));
          NRF_LOG_INFO("DataY in rad/sec : " NRF_LOG_FLOAT_MARKER, 
          NRF_LOG_FLOAT(gyrX));
          NRF_LOG_FLUSH();
           nrf_delay_ms(50);
           eep_WriteByte(0x00051,accelX);
            reg1=eep_readByte(0x00051);
    	if(reg1!=0){
    		NRF_LOG_INFO("\r\n Read value 51 : %d",reg1);
                    NRF_LOG_FLUSH();
                    nrf_delay_ms(5);
    	}
    	else if(reg1==0){
            NRF_LOG_INFO("\r\n can't Read value 51 ");
    	 nrf_delay_ms(5);
    	}
    }
    
    /**
     * @brief Function for main application entry.
     */
    int main(void)
    { bsp_board_init(BSP_INIT_LEDS);
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
         NRF_LOG_INFO("EEPROM get started.\n");
        NRF_LOG_FLUSH();
        Acc_delay_ms(100);
    
    
        E_twi_init();
        Acc_delay_ms(50);
        unsigned char  reg1 = 0;
        
        nrf_delay_ms(1000);
        nrf_delay_ms(5);
    	   reg1=eep_readByte(0x0000);
    	if(reg1!=0){
    		NRF_LOG_INFO("\r\n Read value 00 : %x",reg1);
                    NRF_LOG_FLUSH();
                    nrf_delay_ms(5);
    	}
    
    	else if(reg1==0){
    	 nrf_delay_ms(5);
    	}
            nrf_delay_ms(3000);
    
         eep_WriteByte(0x0000,'S');
        nrf_delay_ms(5);
    	   reg1=eep_readByte(0x0000);
    	if(reg1!=0){
    		NRF_LOG_INFO("\r\n Read value 00 : %x",reg1);
                    NRF_LOG_FLUSH();
                    nrf_delay_ms(5);
    	}
    
    	else if(reg1==0){
    	 nrf_delay_ms(5);
    	}
    
        NRF_LOG_INFO("BMI160 get started.\n");
        NRF_LOG_FLUSH();
        Acc_delay_ms(100);
       // nrf_drv_twi_disable(&m_twi_e);
    
    
        //B_twi_init();
        Acc_delay_ms(50);
    
        BMI_init();
        Acc_delay_ms(100);
        uint8_t reg_addr = BMI160_CHIP_ID_ADDR;
        uint8_t data;
        uint16_t len = 1;
        Acc_delay_ms(1000);
        rslt = bmi160_get_regs(reg_addr, &data, len, &sensor);
        NRF_LOG_INFO("Data:%x", data);
        NRF_LOG_FLUSH();
        Acc_delay_ms(3000);
        
        while (true)
        {
            nrf_delay_ms(250);
            read_sensor_data();
    
            NRF_LOG_FLUSH();
        }
    }
    
    /** @} */
    

    OUTPUT:

    <info> app: EEPROM get started.
    
    <info> app: EEPROM TWI init success...
    <info> app: 
     Read value 00 : 53
    <info> app: 
    Written Sucess
    <info> app: 
     Read value 00 : 53
    <info> app: BMI160 get started.
    
    <info> app: BMI160 Initialized...
    <info> app: sensor Configured...
    <info> app: Data:D1
    <info> app: DataX in m/s^2   : 2.60
    <info> app: DataY in rad/sec : -0.00
    <info> app: 
    Written Sucess
    <info> app: 
     Read value 51 : 2
    <info> app: DataX in m/s^2   : 2.56
    <info> app: DataY in rad/sec : -0.00
    <info> app: 
    Written Sucess
    <info> app: 
     Read value 51 : 2
    

    can you tell me how to save the negative value in eeprom like (-2.05) in an address

  • can you tell me how to save the negative value in eeprom like (-2.05)

    This is standard 'C' - nothing specifically to do with Nordic.

    The EEPROM just stores bytes - it neither knows not cares what those bytes represent.

    So you need to write functions to take your data, and write it to the EEPROM as a sequence of bytes;

    And, conversely, code to read a sequence of bytes from EEPROM and form it into your data.

    https://en.wikipedia.org/wiki/Serialization

  • @awneil, I agree. This is very confusing, even for me

    It seems to be a general problem throughout the Nordic documentation:

    https://devzone.nordicsemi.com/f/nordic-q-a/48848/pin-configuration-limitation/194009#194009

    Disappointed

Related