Help Switching I2C Header

I’m using I2C from an UDOO that uses Arduino/Genuino 101. I’m trying to communicate to a PIC14000 with the Wire.h library. Whilst looking for information on using I2C with my PIC, I found a code that was exactly what I was trying to program. So whats the problem MacDH? The problem is it uses a header file called SoftI2CMaster.h and that header file requires avr/io.h which I do not have. and as far as I know, that header file is for another board. If someone could please help me understand how to use the functions in Wire.h for my program that uses SoftI2CMaster.h, I would greatly appreciate it. I have failed many times trying to convert the program to a different header file.

The program in question:
The only function I dont understand is fetchWord()
This is not the full code. Full code is @ GitHub - PackProbe.ino
Code for SoftI2CMaster.h is @ GitHub - SoftI2CMaster.h

/* Not needed in Wire.h */
#define SDA_PORT PORTD
#define SDA_PIN 7


#define SCL_PORT PORTB
#define SCL_PIN 4

#define I2C_SLOWMODE 1
/* The header file in question */
#include <SoftI2CMaster.h>


// standard I2C address for Smart Battery packs
byte deviceAddress = 11;

// Standard and common non-standard Smart Battery commands
#define BATTERY_MODE             0x03
#define TEMPERATURE              0x08
#define VOLTAGE                  0x09
#define CURRENT                  0x0A
#define RELATIVE_SOC             0x0D
#define ABSOLUTE_SOC             0x0E
#define REMAINING_CAPACITY       0x0F
#define FULL_CHARGE_CAPACITY     0x10
#define TIME_TO_FULL             0x13
#define CHARGING_CURRENT         0x14
#define CHARGING_VOLTAGE         0x15
#define BATTERY_STATUS           0x16
#define CYCLE_COUNT              0x17
#define DESIGN_CAPACITY          0x18
#define DESIGN_VOLTAGE           0x19
#define SPEC_INFO                0x1A
#define MFG_DATE                 0x1B
#define SERIAL_NUM               0x1C
#define MFG_NAME                 0x20   // String
#define DEV_NAME                 0x21   // String
#define CELL_CHEM                0x22   // String
#define MFG_DATA                 0x23   // String
#define CELL4_VOLTAGE            0x3C   // Indidual cell voltages don't work on Lenovo and Dell Packs
#define CELL3_VOLTAGE            0x3D
#define CELL2_VOLTAGE            0x3E
#define CELL1_VOLTAGE            0x3F
#define STATE_OF_HEALTH          0x4F

// I already understand this part
void setup()
{
  Serial.begin(115200);  // start serial for output
  Serial.println(i2c_init());
  pinMode(22,INPUT_PULLUP);
  pinMode(23,INPUT_PULLUP);

  while(!Serial);
  
  i2c_init();
}

// This is the function I cannot figure out how to switch from SoftI2CMaster.h to Wire.h
// byte func is the standard commands defined above
int fetchWord(byte func)
{
  // I2C_WRITE is defined as 0 in SoftI2CMaster.h
  i2c_start(deviceAddress<<1 | I2C_WRITE);
  i2c_write(func);
  // I2C_READ is defined as 1 in SoftI2CMaster.h
  i2c_rep_start(deviceAddress<<1 | I2C_READ);
  byte b1 = i2c_read(false);
  byte b2 = i2c_read(true);
  i2c_stop();
  return (int)b1|((( int)b2)<<8);
}

// This is just basic function calls and prints
void loop()
{

  Console.print("Serial Number: ");
  Console.println(fetchWord(SERIAL_NUM));

  Console.print("Specification Info: ");
  Console.println(fetchWord(SPEC_INFO));
 
  Console.print("Cycle Count: " );
  Console.println(fetchWord(CYCLE_COUNT));
  
  Console.print("Voltage: ");
  Console.println((float)fetchWord(VOLTAGE)/1000);

  Console.print("Full Charge Capacity: " );
  Console.println(fetchWord(FULL_CHARGE_CAPACITY));
  
  Console.print("Remaining Capacity: " );
  Console.println(fetchWord(REMAINING_CAPACITY));

  Console.print("Relative Charge(%): ");
  Console.println(fetchWord(RELATIVE_SOC));
  
  Console.print("Absolute Charge(%): ");
  Console.println(fetchWord(ABSOLUTE_SOC));
  
  Console.print("Minutes remaining for full charge: ");
  Console.println(fetchWord(TIME_TO_FULL));
  
  Console.println(".");
  delay(1000);
}

Here is my attempt of trying to modify the above code:
Wire.h reference @ Arduino - Wire.h

#include <Wire.h>

// Address read from Bus Pirate
//byte battRead = 0x17;
//byte battWrite = 0x16;
// Address read from Bus Scan on Arduino IDE
byte battAddress = 11;

// Standard and common non-standard Smart Battery commands
#define BATTERY_MODE             0x03
#define TEMPERATURE              0x08
#define VOLTAGE                  0x09
#define CURRENT                  0x0A
#define RELATIVE_SOC             0x0D
#define ABSOLUTE_SOC             0x0E
#define REMAINING_CAPACITY       0x0F
#define FULL_CHARGE_CAPACITY     0x10
#define TIME_TO_FULL             0x13
#define CHARGING_CURRENT         0x14
#define CHARGING_VOLTAGE         0x15
#define BATTERY_STATUS           0x16
#define CYCLE_COUNT              0x17
#define DESIGN_CAPACITY          0x18
#define DESIGN_VOLTAGE           0x19
#define SPEC_INFO                0x1A
#define MFG_DATE                 0x1B
#define SERIAL_NUM               0x1C
#define MFG_NAME                 0x20   // String
#define DEV_NAME                 0x21   // String
#define CELL_CHEM                0x22   // String
#define MFG_DATA                 0x23   // String
#define CELL4_VOLTAGE            0x3C   // Indidual cell voltages don't work on Lenovo and Dell Packs
#define CELL3_VOLTAGE            0x3D
#define CELL2_VOLTAGE            0x3E
#define CELL1_VOLTAGE            0x3F
#define STATE_OF_HEALTH          0x4F

void setup()
{
  Serial.begin(115200);  // start serial for output
  while (!Serial);
  Wire.begin();
}

void scan()
{
  byte retval;
  char temp[64];
  for( byte address = 1; address <= 127; address++ ) {
    Wire.beginTransmission(address);
    retval = Wire.endTransmission();
    sprintf(temp, "address: %-4d%-5s", address, (retval == 0 || retval == 3) ? "found" : "");
    Serial.print(temp);
    Serial.print((address % 4) ? '\t' : '\n');
  }
}

// Doesn't work but I dont know if I did it right
int fetchWord(byte func)
{
  Wire.beginTransmission(battAddress);
  Wire.requestFrom(func, 2);
  while(Wire.available()){
    byte b1 = Wire.read();
    byte b2 = Wire.read();
  }
  Wire.endTransmission();
  return (int)b1|((( int)b2)<<8);
}

void loop()
{

  Console.print("Serial Number: ");
  Console.println(fetchWord(SERIAL_NUM));

  Console.print("Specification Info: ");
  Console.println(fetchWord(SPEC_INFO));
 
  Console.print("Cycle Count: " );
  Console.println(fetchWord(CYCLE_COUNT));
  
  Console.print("Voltage: ");
  Console.println((float)fetchWord(VOLTAGE)/1000);

  Console.print("Full Charge Capacity: " );
  Console.println(fetchWord(FULL_CHARGE_CAPACITY));
  
  Console.print("Remaining Capacity: " );
  Console.println(fetchWord(REMAINING_CAPACITY));

  Console.print("Relative Charge(%): ");
  Console.println(fetchWord(RELATIVE_SOC));
  
  Console.print("Absolute Charge(%): ");
  Console.println(fetchWord(ABSOLUTE_SOC));
  
  Console.print("Minutes remaining for full charge: ");
  Console.println(fetchWord(TIME_TO_FULL));
  
  Console.println(".");
  delay(1000);
}

Other references:
MicroChip - PIC14000 DataSheet

Thank you,
MacDH

Your adaptation of the original fetchWord() is close.

Why do you allow it to read "forever" when you know that you only requested two bytes? If you requested two (and you waited for them to arrive) then you should read two. Just remove the while loop. The original had no while loop.

Best-practice would be to check that you did get two bytes as expected and return some error code if not, but this is a very simple function that doesn't really have any way of alerting you to that error.

What happened when you tried it?

Do you have an AVR Arduino to test just this one little piece by itself? That would confirm if the PIC is giving the expected answers.