I2C: Intentando leer múltiples registros, repitiendo primero el primer registro

1

Estoy intentando leer los registros 0x28 a 0x2D de la L3G4200D (giroscopio, hoja de datos ), que es parte de la placa GY-80, usando el esp32 ( I2C info ) como maestro, que forma parte de la placa LOLIN32. Pero en vez de eso, el primer byte se repite ocho veces y no puedo entender por qué. Obtengo el resultado correcto cuando leo los registros uno por uno.

Los registros se encuentran en la hoja de datos aquí:

Este es el paquete I2C visto a través de mi osciloscopio (picoscope):

Amplió la parte de escritura:

Amplió la parte leída:


Estoy usando este código para enviar el paquete:

 
//I2C init:
  i2c_config_t conf;
  conf.mode = I2C_MODE_MASTER;
  conf.sda_io_num = GPIO_NUM_16;
  conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
  conf.scl_io_num = GPIO_NUM_17;
  conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
  conf.master.clk_speed = 400000;
  i2c_param_config(I2C_NUM_0, &conf);
  i2c_driver_install(I2C_NUM_0, conf.mode, 0, 0, 0);

//function call:
  uint8_t gyroData[6];
  getWireRegister(GYRO, OUT_X_L, &gyroData[0], 6); //GYRO = 0x69 , OUT_X_L = 0x28

//function:
bool getWireRegister(uint8_t device, uint8_t reg, uint8_t * receiveData, int amount){
  i2c_cmd_handle_t cmd = i2c_cmd_link_create();                           //create command to tell device what to send and read the registers
  i2c_master_start(cmd);                                                  //startbit
  i2c_master_write_byte(cmd, (device << 1) | I2C_MASTER_WRITE, 0x1);      //send device address and tell it that the master is writing , ack check is enabled
  i2c_master_write_byte(cmd, reg, 0x1);                                    //tell it what register to send , ack check is enabled
  i2c_master_start(cmd);                                                  //repeated startbit to tell it to send stuf to the master
  i2c_master_write_byte(cmd, (device << 1) | I2C_MASTER_READ, 0x1);       //send device address and tell it that the master is reading and it needs to write , ack check is enabled
  if(amount > 1){
    i2c_master_read(cmd, receiveData, amount-1, I2C_MASTER_ACK);          //give the device space to write
  }
  i2c_master_read(cmd, receiveData+amount-1, 1, I2C_MASTER_LAST_NACK);    //give the device space for its last bit and tell the device it is done writing
  i2c_master_stop(cmd);                                                   //stopbit

  i2c_master_cmd_begin(I2C_NUM_0, cmd, 10000);                            //send first I2C message

  i2c_cmd_link_delete(cmd);                                               //delete first message

  return true;
}
    
pregunta Maarten

1 respuesta

3

¡Encontré el problema! Me perdí totalmente la parte de la hoja de datos que explica cómo enviar los paquetes I2C (sección 5.1.1, como se señaló en MaNyYaCk).

Al leer este dispositivo, los 7 bits menos significativos que envíe deben ser la dirección del registro que desea leer, el bit más significativo le indica al dispositivo si debe incrementar la dirección del registro al leer varios bytes.

Para solucionar este problema, tuve que cambiar la siguiente línea de código:

i2c_master_write_byte(cmd, reg, 0x1);    //tell it what register to send , ack check is enabled

Para:

i2c_master_write_byte(cmd, reg | (0b10000000), 0x1);   //tell it what register to send , enables the increment register address bit , ack check is enabled
    
respondido por el Maarten

Lea otras preguntas en las etiquetas