Avoid Wire.requestFrom in program

Well, this is the question, I am working on a system with an FPGA and I am passing a test code from my Arduino to the FPGA, but it turns out that the I2C system of the FPGA is quite basic, I only have read and write. I was able to pass all the code without problem, but I am stuck in this part:

  Wire.beginTransmission(device);
  Wire.requestFrom(device, num);

I looked for a lot of information about requestFrom, I even navigated through the i2c and twi class of the arduino Wire library code, and it seemed like something very complicated to understand. I was hoping someone here can give me a hand on how to rebuild that function with just Write and Read or how to avoid it entirely. Thanks and greetings!.

To use the basic I2C operations you need start() and stop() in addition to read() and write().

Here is how I read three bytes from a sensor using the hardware I2C, assuming that the sensor device is capable of autoincrementing the register address pointer. You really need to know the details of your device, so consult the data sheet.

unsigned char I2C_ReadACK () {

// reads a byte from slave

    TWCR = TW_ACK; // ack = will read more data
    while (!TW_READY); // wait
    return TWDR;
}

unsigned char I2C_ReadNACK () {

// reads a byte from slave

    TWCR = TW_NACK; // nack = not reading more data
    while (!TW_READY); // wait
    return TWDR;
}
// read a 3 byte value, lowest order byte first

signed long I2C_ReadPressureRaw(unsigned char busAddr, unsigned char deviceRegister) {

    unsigned char pxl,pl,ph;
    I2C_Start(busAddr); // send device address
    I2C_Write(deviceRegister | 0x80); // set register pointer, autoincrement
    I2C_Start(busAddr+READBIT); // restart as a read operation
    pxl = I2C_ReadACK(); // read ls byte
    pl = I2C_ReadACK(); // read middle
    ph = I2C_ReadNACK(); // read high
    I2C_Stop(); // stop
    return (int32_t)ph << 16 | (uint16_t)pl << 8 | pxl;
}

The sensor that im trying to use is the ADXL345, i know how to use it on arduino with just the Wire library, but when i try to pass the code, i always read zeros. I dont know why, its stranger...

For help, please read and follow the instructions in https://forum.arduino.cc/t/how-to-get-the-best-out-of-this-forum/681310

The best way of uderstanding the working principle of Wire.requestFrom(arg1, arg2) instruction is to make a setup using two Arduinos. You can write register level codes to read data from Arduino Slave and then apply those codes to read multi-byte data from ADXL345 sensor (Fig-1).

Wire.requesFrom(arg1, arg2) is a high level Arduino Code which is, in fact, the implementation of multi-byte data read operation.

Figure-1:

Hey, thanks for your image, help me a lot!, a i write this (still no work) with your image and @jremington register autoincrement help:

#include <stdio.h>
#include "system.h"
#include "i2c_opencores.h"

int _buff[6];

char DATAX0 = 0x32; //X-Axis Data 0
char DATAX1 = 0x33; //X-Axis Data 1
char DATAY0 = 0x34; //Y-Axis Data 0
char DATAY1 = 0x35; //Y-Axis Data 1
char DATAZ0 = 0x36; //Z-Axis Data 0
char DATAZ1 = 0x37; //Z-Axis Data 1

void readAccel() {
//Read the data
I2C_start(I2C_OPENCORES_0_BASE, 0x53, 0); //Write mode
I2C_write(I2C_OPENCORES_0_BASE, 0x80 | 0x32 | 0x40, 0);
I2C_write(I2C_OPENCORES_0_BASE, 0x53 | 0x80, 1); //1 = Expect ACK
I2C_start(I2C_OPENCORES_0_BASE, 0x53, 0); //Write mode
I2C_write(I2C_OPENCORES_0_BASE, 0x80 | 0x32 | 0x40, 1); //1 = Expect ACK
I2C_start(I2C_OPENCORES_0_BASE, 0x53, 1); //Read mode

int i = 0;
for(i = 0; i < 6; i++)
	_buff[i] = I2C_read(I2C_OPENCORES_0_BASE, 0);//i == 5 ? 1 : 0); //If is the last, expect ACK

//Read the values from the registers and convert to int (Each axis have 10 bits, in 2 Bytes LSB)
//int x = (((int)_buff[1]) << 8) | (int)_buff[0];
//int y = (((int)_buff[3]) << 8) | (int)_buff[2];
//int z = (((int)_buff[5]) << 8) | (int)_buff[4];

//printf("x: %d", x);
//printf(" y: %d", y);
//printf(" z: %d\n", z);
int j;
for(j = 0; j < 6; j++)
	printf("_buff[%d] = %d", j, _buff[j]);

}

int main() {
printf("ADXL345: Initializing...\n");

I2C_init(I2C_OPENCORES_0_BASE, ALT_CPU_FREQ, 100000);
I2C_init(I2C_OPENCORES_0_BASE, ALT_CPU_FREQ, 100000);

//Put the ADXL345 in +- 4G
I2C_start(I2C_OPENCORES_0_BASE, 0x53, 0); //Write mode
I2C_write(I2C_OPENCORES_0_BASE, 0x31, 0);
I2C_write(I2C_OPENCORES_0_BASE, 0x01, 1); //1 = Expect ACK

//Put the ADXL345 in Measurement mode
I2C_start(I2C_OPENCORES_0_BASE, 0x53, 0); //Write mode
I2C_write(I2C_OPENCORES_0_BASE, 0x2D, 0);
I2C_write(I2C_OPENCORES_0_BASE, 0x08, 1); //1 = Expect ACK

while(1) {
	readAccel(); //Read accel (x, y, z)
	usleep(1000000);
}

return 0;
}

sorry if its bad post non-arduino code on the forum, but im realy on blank here. I do some debug print and the read from the registers are zero and im in the point of ask, was its bad???? This is bare-bones code, i delete all variables to hard-coded hex numbers to avoid some data type error, but all is the same.... if any have some idea, i would apreciate it. Thanks and greatings!

Please edit your post to add code tags.

Start simply, and get a one-byte read operation working before moving on. Read the ADXL345 device ID register 0, for example. It should return 0xE5.

Follow SSS Methodology as suggested by @jremington. SSS stands for "Start Small Strategy". Start with soemthing very basic (simple and elementary) and make it work. After that add another inncremental amount of hardware/software and make it work. This way you can finish the project and can have answers of many questions. Abert Einstein has said that the wise people start with someting very simple and then gradually move to the complex.