efficent I2C reading of multiple registers

Hello here,

I am currently trying to use the wire lirbray to read and combine data from two registers. The code I have below does work but i think is not the most efficent. I am trying to reduce the software overhead as much as possible:

unsigned long read_sensor ( int address , int reg, int reg2){
      Wire.beginTransmission(address);
      Wire.write(reg);
      Wire.endTransmission(false);
      Wire.requestFrom(address,2);
      unsigned long result = Wire.read();
      result= result <<8  | Wire.read();
      Wire.endTransmission();

      Wire.beginTransmission(address);
      Wire.write(reg2);
      Wire.endTransmission(false);
      Wire.requestFrom(address,1);
      result = result <<8 | Wire.read();
      Wire.endTransmission();
      return result;

Reg contains the 16 MSB of a sensors data and Reg2 contains the 8 LSB data. but they are two different registers and therefore I cannot just request 4 bytes from the device (I think).

The code above does work but I am trying to find the most efficent method with the lowest overhead to get the data out of the regeisters as it then will be bit-banged out of the arudino onto another micro controller. Also I am not 100% sure wire library is the best method to go if I want the lowest software overhead and lowest instruction cyclees when it comes to I2C.

The device in question is FDC1004 from TI.

below is the entire sketch, its kind of a bit mess but works:

  #include <Wire.h>
  unsigned int temp_bit = 0;
  unsigned int edge_state = 0;
  
// I2C inital
  int address_loc = 0b1010000; // Device address
  unsigned long read_data[3];

  //pin number bits 
  int control = 4;
  int current_bit =2;
  int rdy_status = 3;
  
  //loop timeout control
  int timeout;

void setup() {
 
  Wire.setClock(400000);
  Wire.begin(); // Initiate the Wire library
  Serial.begin(115200);
  communication_inital_setup();
  spi_inital_setup();
  Serial.println("done");
  
}


void loop() {
  unsigned long read_data[3];
  unsigned long temp_data=0b101110010011101011101010;
  byte z;
  byte last_state=0;
  z=PIND&(1<<4);
  if (z>0 && last_state==0){
    read_data[0] = read_sensor( address_loc,0x00,0x01);
    read_data[0] = read_sensor( address_loc,0x00,0x01)
    transfer_data(temp_data);
    last_state=z;
    }
    //read_data[0] = read_sensor( address_loc,0x00,0x01);
    //Serial.println(read_data[0]);
    //delay(1000);
    
}
      //read_data[0] = read_sensor( address_loc,0x00,0x01);
      //read_data[1] = read_sensor( address_loc,0x02,0x03);
      //read_data[2] = read_sensor( address_loc,0x04,0x05);
      //read_data[3] = read_sensor( address_loc,0x06,0x07);





///////////////////////////////////////////////////////////////////////////////////////////
//all functions below



void spi_inital_setup(){
      write_data(address_loc,0x0C,0b110111110000);  //setup data for power on.
      delay(100);
      write_data(address_loc,0x08,0b0001110000000000);
      delay(100);
      write_data(address_loc,0x09,0b0011110000000000);
      delay(100);
      write_data(address_loc,0x0A,0b0101110000000000);
      delay(100);
      write_data(address_loc,0x0B,0b0111110000000000);
}

void communication_inital_setup(){
  pinMode(current_bit, OUTPUT);
  pinMode(rdy_status, OUTPUT);
  pinMode(control, INPUT);
  
}


void transfer_data(unsigned long temp){
  byte last_state = 0;
  byte bitcount=0;
  int timeout=0;
  while(bitcount<24){
    byte z=PIND&(1<<4);
    if (z>1 && last_state==0){
      PORTD = (temp &0b1) <<2;
      last_state=1;
    }
    if (z<1 && last_state==1){       
      temp>>=1;
      //PORTD = (temp_data &0b1) <<2;
      last_state=0;
      bitcount++;
    }
      timeout++;
    if (timeout>10000){
          Serial.println("fail");
          return;
    }
  }    
}



void write_data ( int address,  int reg, int data){
    byte high[2];
    high[0]=highByte(data);
    high[1]=lowByte(data);
    Wire.beginTransmission(address); // Begin transmission to the Sensor 
    Wire.write(reg);
    Wire.write(high,2);
    Wire.endTransmission();
}




unsigned long read_sensor ( int address , int reg, int reg2){
      Wire.beginTransmission(address);
      Wire.write(reg);
      Wire.endTransmission(false);
      Wire.requestFrom(address,2);
      unsigned long result = Wire.read();
      result= result <<8  | Wire.read();
      Wire.endTransmission();

      Wire.beginTransmission(address);
      Wire.write(reg2);
      Wire.endTransmission(false);
      Wire.requestFrom(address,1);
      result = result <<8 | Wire.read();
      Wire.endTransmission();
      return result;
 
}

the part of write_data function is used to bitbang the data from the arduino onto a stm32. The end goal would be multiple of these arduino bit banging data onto the stm at the same time.

fdc1004.pdf (1.75 MB)

I updated the code to include the whole thing,

sadly the device cannot auto increment.

I also have attached the datasheet, and the register in question are 0x00 and 0x01, measurements of the other 3 sensors are also required but at this stage I am trying to do sensor 1 (0x00 and 0x01)

fdc1004.pdf (1.75 MB)