Código del puerto I2C de Arduino a Sercom

1

Tengo un MPU-6050 (giro / acelerómetro), es conectado a Arduino a través de I2C (a través de Wiring.h) y todo funciona bien. Ahora estoy tratando de portar este código a un Atmel SAMD20 (Cortex M0 +), que se incluye con Sercom I2C bibliotecas. Tengo una conexión con el dispositivo (parece), y al escribir todos los rendimientos está bien, pero no puedo leer nada ...

Arduino

const int MPU_addr=0x68;  // I2C address of the MPU-6050

void setup() {
  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
}

void loop() {
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr, 14, true);  // request a total of 14 registers
  AcX = Wire.read() << 8 | Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)

SAMD20

static enum status_code writeByte(struct i2c_master_module* module, const uint8_t byte) 
{
    static uint8_t buffer[1];
    buffer[0] = byte;
    struct i2c_master_packet packet = {
        .address = 0x68,
        .data = buffer,
        .data_length = 1,
    };

    return i2c_master_write_packet_wait_no_stop(module, &packet);
}

struct i2c_master_module module;

struct i2c_master_config config;
i2c_master_get_config_defaults(&config);

enum status_code initStatus = i2c_master_init(&module, SERCOM2, &config);
i2c_master_enable(&module);

enum status_code s1 = writeByte(&module, 0x6b); // PWR_MGMT_1 register
enum status_code s2 = writeByte(&module, 0x0);  // 0x0 wakes module up
i2c_master_send_stop(&module);

enum status_code s3 = writeByte(&module, 0x3b); 
static uint8_t buffer[14];
struct i2c_master_packet packet = {
    .address = 0x68,
    .data = buffer,
    .data_length = 14,
};
enum status_code s4 = i2c_master_read_packet_wait(&module, &packet);

Por lo tanto, todos mis valores de retorno siempre están bien, pero el valor de buffer es basura (todos los 0, excepto en buffer[10] ).

¿Alguien sabe más sobre I2C y Sercom?

Editar: Al leer el byte de quién soy yo (0x75) se obtiene el valor correcto. Así que empiezo a preguntarme si el dispositivo realmente sale del modo de suspensión.

    
pregunta Jan Jongboom

1 respuesta

1

Entonces, en Arduino parece que se escriben dos paquetes ( 0x6b y 0x0 ). Este no es el caso. Para iniciar, el sensor debe enviar un solo paquete con un valor de dos bytes. Después de cambiar el código para reflejar que el sensor comenzó a funcionar y pude leer los valores.

enum status_code powerOnStatus;
{
    uint8_t retryCount = 0;

    static uint8_t buffer[2] = { 0x6b, 0x0 }; // power on packet
    struct i2c_master_packet packet = {
        .address = 0x68,
        .data = buffer,
        .data_length = 2,
    };

    while ((powerOnStatus = i2c_master_write_packet_wait(&module, &packet)) != STATUS_OK)
    {
        if (++retryCount >= maxRetries) break;
    }
}

Escribí sobre otros problemas que encontré al portar el código aquí .

    
respondido por el Jan Jongboom

Lea otras preguntas en las etiquetas