I'm having a MPU-6050 (gyro / accelerometer), it's connected to Arduino over I2C (via Wiring.h) and everything works well. Now I'm trying to port this code to an Atmel SAMD20 (Cortex M0+), which is bundled with Sercom I2C libraries. I have a connection to the device (it seems), and writing all yields OK, but I cannot read anything…
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);
So all my return values are always OK, but the value of buffer
is garbage (all 0's except at buffer[10]
).
Anyone knows more about I2C and Sercom?
Edit: Reading the who am I byte (0x75) yields in the correct value. So I'm starting to wonder whether the device actually gets out of sleep mode.
Best Answer
So on Arduino it seems like two packets are written (
0x6b
then0x0
). This is not the case. To start up the sensor needs to send one single package with two bytes value. After I changed the code to reflect that the sensor started working and I could read values.I wrote about other issues I ran into while porting the code here.