This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

SENSOR-CONTROLLER-STUDIO: Sensor Controller Fails on 2nd read - MPU9250

Part Number: SENSOR-CONTROLLER-STUDIO
Other Parts Discussed in Thread: CC1350, CC2650

I am trying to communicate with an MPU9250 via the sensor controller. I have a gy-91 breakout board that combines a BMP280 and MPU9250 connected to a 2650 launchpad.

I have no trouble reading the BMP280, but on the 2nd i2c transaction with the MPU9250, I get a i2cstatus of 1. I can read the whoami byte from the 9250, but anything after that fails.

Any idea on how to troubleshoot this without a oscilloscope?

    i2cStart();
    i2cTx(I2C_OP_WRITE | (MPU9250_I2C_ADDR<<1));
    i2cTx(MPU9250_WHO_AM_I); //WHO_AM_I is the register for device ID
    i2cRepeatedStart();
    i2cTx(I2C_OP_READ | (MPU9250_I2C_ADDR<<1));
    i2cRxAck(output.whoamiMPU9250);
    i2cStop();


    i2cStart();
    i2cTx(I2C_OP_WRITE | (MPU9250_I2C_ADDR<<1));
    i2cTx(MPU9250_WHO_AM_I); //<<<<<< fails here with i2cstatus on 1
    i2cRepeatedStart();
    i2cTx(I2C_OP_READ | (MPU9250_I2C_ADDR<<1));
    i2cRxAck(output.whoamiMPU9250);
    i2cStop();

  • Hi,

    It is hard to give any good advice on how to troubleshoot this without actually looking at the I2C bus. i2cstatus 1 means you received an NACK. I assume you might put the device in some kind of busy state after the first transfer.

    Reading the MPU9250 datasheet, a single byte read operation should look like:

    START (M) -> I2CAddress+write (M) -> ACK (S) -> Register (M) -> ACK (S) -> START (M) -> I2CAddress+read(M) -> ACK (S) -> DATA (S) -> NACK (M) -> STOP (M)

    This mean your code should look something like:

    i2cStart();
    i2cTx(I2C_OP_WRITE | (MPU9250_I2C_ADDR<<1));
    i2cTx(MPU9250_WHO_AM_I); //<<<<<< fails here with i2cstatus on 1
    i2cRepeatedStart();
    i2cTx(I2C_OP_READ | (MPU9250_I2C_ADDR<<1));
    i2cRxNack(output.whoamiMPU9250);
    i2cStop();

    Try changing from i2cRxAck to i2cRxNack and see if this makes a difference.

  • Thanks. That seems to have worked.

    It looks like the MPU9250 returns 0xFF when you write to the control registers. In the other libraries I've used it doesn't seem to matter if I read this byte or not. Likewise with the BMP280, I can do this without issue:

        i2cStart();
        i2cTx(I2C_OP_WRITE | (BMP280_I2C_ADDR<<1));
        i2cTx(BMP280_RESET);
        i2cTx(BMP280_RESET_VAL);
        i2cStop();

    I just assumed that it work the same for the 9250.

    My reading of the sensor controller studio help page indicates that the i2cStart(); call should reset the i2cstatus, but if I dont nack that byte, it screws up any future i2c reads. Shouldn't there be a way to recover from this condition without a full power cycle?

  • I'm getting quite a bit further on this, but am running into the same issue when trying to set the bypass to enable the magnetometer:

    These all work with the Nack:

        i2cStart();
        i2cTx(I2C_OP_WRITE | (MPU9250_I2C_ADDR<<1));
        i2cTx(MPU9250_WHO_AM_I); //WHO_AM_I is the register for device ID
        i2cRepeatedStart();
        i2cTx(I2C_OP_READ | (MPU9250_I2C_ADDR<<1));
        i2cRxNack(output.whoamiMPU9250);
        i2cStop();
        
        
        // wake up device
        i2cStart();
        i2cTx(I2C_OP_WRITE | (MPU9250_I2C_ADDR<<1));
        i2cTx(MPU9250_PWR_MGMT_1);
        i2cTx(0x00 | MPU9250_BIT_H_RESET_MGT); // Clear sleep mode bit (6), enable all sensors
        i2cRxNack(output.pwrmgt);
        i2cStop();
        
        
        // get stable time source
        i2cStart();
        i2cTx(I2C_OP_WRITE | (MPU9250_I2C_ADDR<<1));
        i2cTx(MPU9250_PWR_MGMT_1);
        i2cTx(0x01); // Auto select clock source to be PLL gyroscope reference if ready else
        i2cRxNack(output.pwrmgt);
        i2cStop();
        
        
        i2cStart();
        i2cTx(I2C_OP_WRITE | (MPU9250_I2C_ADDR<<1));
        i2cTx(MPU9250_PWR_MGMT_2);
        i2cTx(MPU9250_BIT_DISABLE_GYRO); // disable the gyro
        //i2cTx(MPU9250_BIT_DISABLE_GYRO | MPU9250_BIT_DISABLE_ACCELL); // disable the gyro & accelerometer
        i2cRxNack(state.state3);
        i2cStop();
        
        
        // Disable I2C master
        i2cStart();
        i2cTx(I2C_OP_WRITE | (MPU9250_I2C_ADDR<<1));
        i2cTx(MPU9250_I2C_MST_CTRL);
        i2cTx(0x00);
        i2cRxNack(state.state3);
        i2cStop();
        
        
        i2cStart();
        i2cTx(I2C_OP_WRITE | (MPU9250_I2C_ADDR<<1));
        i2cTx(MPU9250_CONFIG);
        i2cTx(0x00);
        i2cRxNack(state.state3);
        i2cStop();
        
        
        i2cStart();
        i2cTx(I2C_OP_WRITE | (MPU9250_I2C_ADDR<<1));
        i2cTx(MPU9250_SMPLRT_DIV);
        i2cTx(1);
        i2cRxNack(state.state3);
        i2cStop();
        
        
        
        i2cStart();
        i2cTx(I2C_OP_WRITE | (MPU9250_I2C_ADDR<<1));
        i2cTx(MPU9250_GYRO_CONFIG);
        i2cTx(0x00);
        i2cRxNack(state.state3);
        i2cStop();
        
        
        
        i2cStart();
        i2cTx(I2C_OP_WRITE | (MPU9250_I2C_ADDR<<1));
        i2cTx(MPU9250_ACCEL_CONFIG1);
        i2cTx(0x08 | 0x06);
        i2cRxNack(state.state3);
        i2cStop();
        
        
        i2cStart();
        i2cTx(I2C_OP_WRITE | (MPU9250_I2C_ADDR<<1));
        i2cTx(MPU9250_ACCEL_CONFIG2);
        i2cTx(0x00);
        i2cRxNack(state.state3);
        i2cStop();
        

    But when I do this following the above, things fall apart:

        //Enable the bypass mode for the AK8963
        i2cStart();
        i2cTx(I2C_OP_WRITE | (MPU9250_I2C_ADDR<<1));
        state.state1 = state.i2cStatus;
        i2cTx(MPU9250_INT_PIN_CFG);
        state.state2 = state.i2cStatus;
        i2cTx(MPU9250_BIT_BYPASS_MODE | MPU9250_BIT_LATCH_EN);
        state.state3 = state.i2cStatus;
        i2cRxNack(state.state4);
        i2cStop();

    Interestingly, this runs fine (states 1, 2, & 3 are all 0, state 4 is 0xFF), but the next i2c operation stumbles. And I have to do a power cycle to recover.

  • Ok, I got my hands on a scope, but I'm not sure how to read the output. This is in the failure state. I run all the code above including writing the bypass bits to the MPU9250, and then I go to the execution code where I am repeatedly reading the BMP280 (which doesn't respond in this state)

    The above scope should be corresponding to this SCS code:

        //read the pressure
        i2cStart();
        i2cTx(I2C_OP_WRITE | (BMP280_I2C_ADDR<<1));
        i2cTx(BMP280_PRESS_MSB);
        i2cRepeatedStart();
        i2cTx(I2C_OP_READ | (BMP280_I2C_ADDR<<1));
        i2cRxAck(cfg.rawpressure[0]);
        i2cRxAck(cfg.rawpressure[1]);
        i2cRxNack(cfg.rawpressure[2]);
        i2cStop();
    

  • And here is a shortened version leading up to the failure:

    Which should be the following code:

        i2cStart();
        i2cTx(I2C_OP_WRITE | (MPU9250_I2C_ADDR<<1));
        i2cTx(MPU9250_WHO_AM_I); //WHO_AM_I is the register for device ID
        i2cRepeatedStart();
        i2cTx(I2C_OP_READ | (MPU9250_I2C_ADDR<<1));
        i2cRxNack(output.whoamiMPU9250);
        i2cStop();
    
    
        //Enable the bypass mode for the AK8963
        i2cStart();
        i2cTx(I2C_OP_WRITE | (MPU9250_I2C_ADDR<<1));
        i2cTx(MPU9250_INT_PIN_CFG);
        i2cTx(MPU9250_BIT_BYPASS_MODE | MPU9250_BIT_LATCH_EN);
        i2cRxNack(state.nacktest);
        i2cStop();
    //anything after this fails with i2cstatus == 0x01 i2cStart(); i2cTx(I2C_OP_WRITE | (AK8963_ADDRESS<<1)); i2cTx(AK8963_WHO_AM_I); //WHO_AM_I is the register for device ID i2cRepeatedStart(); i2cTx(I2C_OP_READ | (AK8963_ADDRESS<<1)); i2cRxNack(output.whoamiAK8963); i2cStop();

    output.whoamiAK8963 is set to 0x01, and anything following this also fails, even reading from another device (see the previous post)

  • Hi,

    Seems like you got your hand on a saleae analyzer, you should be able to add a "Analyzer" to your input on the right side.

    Add a new I2C analyzer there and it will help you decode the output. This will also make it possible to actually tell what is going on without trying to count cycles :)

    In your case, are you sure on the i2cRxNack after the line i2cTx(MPU9250_BIT_BYPASS_MODE | MPU9250_BIT_LATCH_EN)?
    You are not performing any read from the device what I can see, therefor you should not perform a RX NACK at the end of the sequence, it is possible that this is messing it up for you.

    I recommend page 34-35 in the MPU9250 datasheet, they contain good images showing the expected flow of write/read operations.

  • Thanks, that helps a lot on deciphering the plot.

    Am I supposed to be calling i2cRxAck() in between each i2cTx()? I'm still unclear on why I had to call i2cRxNack() to get the other MPU9250 write operations to work. The manual on page 34 says nothing about Nacks (for write operations), and my assumption is that I do not need to explicitly call i2cRxAck()... at least that is the case for the BMP280 for write operations

        //Enable the bypass mode for the AK8963
        i2cStart();
        i2cTx(I2C_OP_WRITE | (MPU9250_I2C_ADDR<<1));
        i2cTx(MPU9250_INT_PIN_CFG);
        i2cTx(MPU9250_BIT_BYPASS_MODE | MPU9250_BIT_LATCH_EN);
        i2cStop();
    
    //the analyzer deciphered up to here
    
    //the following was not deciphered, but shows up on the plot lines. My guess is because the bypass was not enabled, so the AK8963 is not reachable. Still, if I delete the following lines, other communications fail as well.
    
    
        i2cStart();
        i2cTx(I2C_OP_WRITE | (AK8963_ADDRESS<<1));
        i2cTx(AK8963_WHO_AM_I); //WHO_AM_I is the register for device ID
        i2cRepeatedStart();
        i2cTx(I2C_OP_READ | (AK8963_ADDRESS<<1));
        i2cRxNack(output.whoamiAK8963);
        i2cStop();
        
        
        i2cStart();
        i2cTx(I2C_OP_WRITE | (AK8963_ADDRESS<<1));
        i2cTx(AK8963_CNTL1); //control reg
        i2cTx(AK8963_BIT_MODE_CONTINUOUS_8HZ); //set to 8Hz
        i2cRxNack(state.nacktest);
        i2cStop();
    
    

    fghjg

  • This one might be a bit more straightforward. Here I'm reading the whoami byte (which works), then writing the int_pin register, then I try to read the whoami again (which worked, but now doesn't after the intpin write)

        i2cStart();
        i2cTx(I2C_OP_WRITE | (MPU9250_I2C_ADDR<<1));
        i2cTx(MPU9250_WHO_AM_I); //WHO_AM_I is the register for device ID
        i2cRepeatedStart();
        i2cTx(I2C_OP_READ | (MPU9250_I2C_ADDR<<1));
        i2cRxNack(output.whoamiMPU9250);
        i2cStop();
    
    
        //Enable the bypass mode for the AK8963
        i2cStart();
        i2cTx(I2C_OP_WRITE | (MPU9250_I2C_ADDR<<1));
        i2cTx(MPU9250_INT_PIN_CFG); //0x37
        i2cTx(MPU9250_BIT_BYPASS_MODE | MPU9250_BIT_LATCH_EN); //0x22
        i2cStop();
        
    //now I cant read the whomi byte anymore    
    i2cStart(); i2cTx(I2C_OP_WRITE | (MPU9250_I2C_ADDR<<1)); i2cTx(MPU9250_WHO_AM_I); //WHO_AM_I is the register for device ID i2cRepeatedStart(); i2cTx(I2C_OP_READ | (MPU9250_I2C_ADDR<<1)); i2cRxNack(output.whoamiMPU9250); i2cStop();

  • "Am I supposed to be calling i2cRxAck() in between each i2cTx()? I'm still unclear on why I had to call i2cRxNack() to get the other MPU9250 write operations to work. The manual on page 34 says nothing about Nacks (for write operations), and my assumption is that I do not need to explicitly call i2cRxAck()..."


    - When you are performing a write operation, you are not expected to ACK or NACK anything, that is the slaves responsibility.       When you are performing a read operation (setup by doing a i2xTx(I2C_OP_READ | ... ) call, you are expected to do rxAck or  rxNack for each byte the slave sends you. 

    In short you can say that whom ever is receiving data need to perform the ACK/NACK. The NACK is performed only for the last byte of data to indicate the end.

    So for a straight write operation (no I2C_OP_READ) you never need to send any ACK/NACK (seen as there is no "ACK" field in the picture on page 34).

    Based on all the spikes and the clock signal after enabling the bypass, I would look into the state of the AUX I2C port and see if this is OK as you are actually connecting the two busses together by setting "MPU9250_BIT_BYPASS_MODE ".

  • Sorry, I've been traveling the past few days.

    I think I'm on the trail to a solution, but am still stuck on enabling the magnetometer. I picked over the other 9250 communication code in the higher level libraries and there are some strategic delays after key operations. In particular, after the reset command and after setting the bypass.

    Your description of the I2C communication is how I understand it, and how it works for the BMP280. If I'm doing a simple write to a register, I shouldn't have to ack/nack. Here's another trace that might shed some light on the issue. I'm doing a simple write (of 0x80) to register 0x6B. Then I stop/start to do another operation, but the trace shows a Nack

    That corresponds to this:

        i2cStart();
        i2cTx(I2C_OP_WRITE | (MPU9250_I2C_ADDR<<1));
        i2cTx(MPU9250_WHO_AM_I); //WHO_AM_I is the register for device ID
        i2cRepeatedStart();
        i2cTx(I2C_OP_READ | (MPU9250_I2C_ADDR<<1));
        i2cRxNack(output.whoamiMPU9250);
        i2cStop();
        
        
        // wake up device
        i2cStart();
        i2cTx(I2C_OP_WRITE | (MPU9250_I2C_ADDR<<1));
        i2cTx(MPU9250_PWR_MGMT_1);
        i2cTx(0x00 | MPU9250_BIT_H_RESET_MGT); // Clear sleep mode bit (6), enable all sensors
        //i2cRxNack(output.pwrmgt); ///////////// I shouldnt have to Nack this since its just a write....
        i2cStop();

    //if I dont Nack, but add this line, it works:
    fwDelayUs(100*1000, FW_DELAY_RANGE_1_MS);

    //now the Nack spills over and causes this to fail (unless I enable the delay above) i2cStart(); i2cTx(I2C_OP_WRITE | (MPU9250_I2C_ADDR<<1)); i2cTx(MPU9250_WHO_AM_I); //WHO_AM_I is the register for device ID i2cRepeatedStart(); i2cTx(I2C_OP_READ | (MPU9250_I2C_ADDR<<1)); i2cRxNack(output.whoamiMPU9250); i2cStop();

    There is a 10ms delay after the bypass, but that still isnt working... I also dont know how to recover from this condition without a power cycle. In the meantime, I am driving the VCC line on the sensor board from a GPIO to recover.

  • When you wake up the device, why do you want to reset the whole device?

    // wake up device
        i2cStart();
        i2cTx(I2C_OP_WRITE | (MPU9250_I2C_ADDR<<1));
        i2cTx(MPU9250_PWR_MGMT_1);
        i2cTx(0x00 | MPU9250_BIT_H_RESET_MGT); // Clear sleep mode bit (6), enable all sensors
        //i2cRxNack(output.pwrmgt); ///////////// I shouldnt have to Nack this since its just a write....
        i2cStop();

    Does the device work if you add a longer delay after this statement ( > 10 ms)?

    The delay you are using support a maximum of 1 ms, while you enter 100*1000 us = 100 ms:

    //if I dont Nack, but add this line, it works
    fwDelayUs(100*1000, FW_DELAY_RANGE_1_MS);

    I'm not sure what happens in this case, but today you don't have any 100 ms delay between second last and last transaction.
    I suggest changing to FW_DELAY_RANGE_100_MS and see if you get the 100ms delay you expect.

  • I'm referencing code from a number of different sources and they all send that reset after a power on. I don't know if that is strictly required, but I don't think it hurts anything. That also comes well before setting the bypass. You can see the TI code in C:\ti\simplelink_cc13x0_sdk_1_60_00_21\source\ti\mw\sensors\SensorMpu9250.c (I wish there were a corresponding example for the sensorcontroller).

    /*
     *  ======== SensorMpu9250_powerOn ========
     */
    void SensorMpu9250_powerOn(void)
    {
        // Turn on power supply
        PIN_setOutputValue(hMpuPin,Board_MPU_POWER, Board_MPU_POWER_ON);
        DELAY_MS(100);
        SensorMpu9250_reset();
    }
    

    As for the delay, according to the scope, there is a 100ms delay. The help documentation for fwDelayUs() could use some clarification on the range parameter. If delay is in microseconds, why have a range (and shouldn't it be a limit)? My reading of it was that the range was a variability of the delay, but a limit makes more sense... still it didnt seem to cap the delay with the 1MS range.

  • Hummm, I don't know if I changed anything else along the way, but now following setting the bypass, the communication looks corrupt (I suppose I could have missed this before, but I don't think so since it looks bad even to my untrained eye). I think the only thing I changed was fwDelayUs(100*1000, FW_DELAY_RANGE_1_MS); to fwDelayUs(100*1000, FW_DELAY_RANGE_100_MS);  but as in the last post, the apparent time delay didn't change.

    This is just a general i2c request following setting the bypass. I believe its to the BMP280, but the point is the clock is all screwy (top trace). I would think resistors might be the culprit, but it works before the bypass, and the bypass is internal to the MPU9250, so I don't think any external circuitry should cause this (or if it did, wouldn't it affect the communication before setting the bypass?)

  • Ok, well this is super frustrating. I know this breakout board for the 9250 works on an ESP32 and Arduino without issue (including the bypass mode). I know the 9250 (in general) works in bypass mode because its on the sensortag. Unfortunately, for some reason the MPU9250 on the sensortag is not on pins that can talk to the sensor controller, so I'm forced to use the breakout board on a launchpad to prototype the SCS configuration.

    Since I'm at my wits end, I tried porting the high level CCS sensortag code over to the launchpad to talk on pins 4&5, and that fails in the exact same way as the low level SCS code (works up until the bypass mode).

    So I guess the upshot is this is not a sensor controller issue. I'm still baffled why this breakout board would work fine on a non-TI device, and work fine on the TI device up until the bypass operation. And that same bypass code works on another TI device. The breakout board is probably to blame, but again, it works on a non TI device and mostly works on a TI device.
  • Looking at the trace you provided back when you introduced the delay, there was no 100ms between the reset (writing 0x80 to 0x6B) and the next write:

    I'm a bit confused by the I2C clock after the bypass is enabled, it almost looks like there is some data interference or something.
    I tried to dig up some schematics for the gy-91 device and from what I can see the MPU and BMP are both connected on the same I2C bus. Are you sure you need to enable the bypass?

  • I probably should have posted more detailed snapshots of the trace.

    The bypass is to access the magnetometer on the MPU9250. Its a bit screwy how they have the magnetometer on a seperate bus internally and you have to set the bypass bit to connect it to the main bus, but it does work (at least on the sensortag, but the pins prevent reading it from the sensor controller)

    I need to read both the 9250 and 280, and to do that from the sensor controller, they need to be on the same bus. That clock issue occurs whether I’m reading the 280 or not. It seems like it’s entirely tied to connecting the magnetometer to the bus via that bypass bit.
  • Ah I missed that detail, tricky wiring. It does seem like you can still access the magnetometer data anyway by setting up the MPU to read the data for you (i.e you only need to use bypass if you want direct access to the magnetometer or if you have aux. sensors.

    As the bus seems to go crazy when the bypass is enabled, could you check what the state of the AUX pins are before and after (and in between transfers)?
    For me it seems like there is something wonky with the gy-91 module. As the I2C is a bit-banged implementation, I can't se any reason for the CLK to freak out like that unless something was actually messing with the bus lines.
  • I'd rather address the magnetometer directly, but yes, that is an option I have been avoiding. I was saving that as a last resort short of switching to another sensor device (which might be the better option as the 9250's complexities can be rather frustrating)

    I ordered a completely different 9250/280 breakout board that should be here tomorrow and I'll report back if that works or not.
  • I ordered another breakout board that looks substantially different than the GY-91 (this one www.amazon.com/.../)

    The bus is not going crazy after setting the bypass on this board, but the magnetometer is not responding after setting the bypass. Progress I guess. Maybe they are just bad boards?
  • Could be the layout of them differs in terms of the AUX pins and that is what causes the I2C interference in one case.
    It is always possible to get a "bad board", on the new one, what is the response/behavior when trying to interface with the magnetometer? Can you still communicate with the 9250?
  • After trying 3 completely different breakout boards, I decided to dust off the ESP32 just to be sure. Unsurprisingly, all three breakout boards worked flawlessly on the ESP32. I really miss the ease of development on that processor.

    I'm at a loss. Any ideas why the MPU9250 works fine on the cc1350 sensortag, works fine on a couple different breakout boards on the ESP32, but when I try and connect those same breakout boards to the launchpad, the magnetometer doesnt work? I'd suspect wiring issues if the sensor didnt work at all, but I can read accelerometer data fine, it just wont go into bypass mode to get through to the magnetometer.
  • When wiring the boards up to use the SCS, are you adding in any pull-ups for the I2C lines?
  • One of the breakout boards I tried has that called out on the schematic:

    And SJ1 is set on the board, so those pullups should be wired to VDD. I'm way out of my element when it comes to circuitry, but I think this is sufficient. Especially since the accelerometers work. If it were a resistor issue, wouldnt that also not work?

  • So the way you are wiring it up to the chip is basically VCC, GND, SDA and SCL?

    The reason I asked about the pull-ups was just to be sure as the problem seemed to appear when connecting the AUX_I2C bus with the main I2C bus.
    I will see if I can find a MPU9250 break out board and do some testing myself on this.

  • Yes, just connecting the 4 pins (vdd, gnd, scl, sda).

    The spark fun board also breaks out the aux lines, which I did try, but it just occurred to me that those would have required additional pullups. Unfortunately I’m on the road and won’t get a chance to try that for another week or two.

  • Hi,

    I have modified a CC2650 sensortag so that the MPU-9250 could be connected to the sensor controller and I ran a test where I did the following:

    * Enable BY-PASS mode.

    * Read out MPU-9250 "Who Am I"

    * Read out AK8963 (Magnetometer) Device ID

    I do this using this example code:

    "Initialization code"
    // Configure and start the next measurement
    i2cStart();
    i2cTx(I2C_OP_WRITE | (MPU_I2C_ADDR));
    i2cTx(0x0037); // Bypass config
    i2cTx(0x0022); // Enable bypass
    i2cStop();
    
    // Schedule the first execution
    fwScheduleTask(1);
    
    "Execution code"
    // Configure and start the next measurement
    i2cStart();
    i2cTx(I2C_OP_WRITE | (MPU_I2C_ADDR));
    i2cTx(0x0075); // Who am i?
    i2cRepeatedStart();
    i2cTx(I2C_OP_READ | (MPU_I2C_ADDR));
    i2cRxNack(output.value);
    i2cStop();
    
    // Configure and start the next measurement
    i2cStart();
    i2cTx(I2C_OP_WRITE | (0x000C << 1)); // Magnetometer
    i2cTx(0x0000); // Device ID
    i2cRepeatedStart();
    i2cTx(I2C_OP_READ | (0x000C << 1));
    i2cRxNack(output.valueAfter);
    i2cStop();
    
    // Schedule the next execution
    fwScheduleTask(1);

    When I do this I have no problem reading out the magnetometer ID or who am I register continuously multiple times. Conclusion, it is possible to do what you want using the sensor controller. Why the breakout boards does not work is the real question.

    After my HW modifications the resulting connecting is MPU I2C -> CC2650 DIO5 and DIO 6 (pulled to VCC by 10k resistors), VCC + GND. I also noted that the AUX pads are left unconnected. 

     

  • How did you modify the sensortag?
  • Hi,

    Here is a crude drawing of how I modified the hardware.

  • Hi,

    Have you been able to test my modifications out?
  • Sorry, I'm still out on the road and wont be back till Friday. I don't know that I have the skills to modify the PCB, but I am going to try connecting directly to the AUX pins on the sparkfun breakout board (this time with pullups) to see if I can talk to the magnetometer without the bypass. I also have an integrated prototype board being designed, but that's still a few weeks out. I think I'll be able to control the sourcing of the chips better than the breakout boards from amazon.

  • No worries, let me know how it works out.

    I will mark the thread as "TI think resolved" for now as I can not reproduce this and it seems to be a hardware error and not an actual SCS problem. Just continue posting here if any new information pops up!
  • Sorry for the delay. I finally had a chance to sit back down with this and am still at a loss. I can only say that there must be some incompatibility with all of these breakout boards and the TI board. Its entirely possible that I am doing something wrong, but I used your code verbatim and can read the whoami from the MPU9250, but not the AK8963 (after setting bypass mode). I even started a fresh project, just to be sure.

    I also tried (via the the sparkfun board) to connect to the auxscl and auxsdl pins with 4.7k pullups, but was still unable to read the magnetometer... although I'm not quite sure it should be readable in that configuration.


    I do appreciate you investigating this. I still cannot talk to the magnetometer, but since you proved it is possible, the only explanation I can come up with is a hardware issue with these breakout boards (or the launchpad?).
  • Hi Spanky,

    While I can't find any major difference between the Sparkfun board and the SensorTag, you could try to ground the FSYNC signal as this is the only clear difference between them in terms of wire up.

    Unfortunately I don't have any of those board here to test with but I doubt that is a problem due to the launchpad. However, I agree with you it sure seems to be a hardware issue somewhere in this mess. What pins are you using on the SCS to interface with the sensor?
  • I tried grounding FSYNC, but that didn't fix it.

    I'm using pins 4scl and 5sda on the 2650 launchpad, which appear to be the preferred pins. I do have an 1350 and 1352 launchpad that I could try.... which I just did as I was writing this response and the 1352 WORKED!!!!!! Holey crap I cant believe it. I just tried the 2650 again just to be sure and no dice on the bypass mode.

    M-W I want to sincerely thank you for your persistence on this. I've come across so many posts here that are closed without a resolution so it is really refreshing that you took the time to see it through. Please pass this along to your corporate overlords, or let me know how to thank them directly.

    I am mildly annoyed with myself that I spent so much time with this when the answer was literally inches away on my desk (albeit intricately wired to another project), but that's pretty-much my fault for not trying the obvious. Do you think the 2650 launchpad is just a bad board, or could it be some design flaw?
  • Hi Spanky,

    You are welcome, I'm here to help :)

    Just for the sake of it. could you try using DIO6 as SCL and DIO5 as SDA and see if that works on the CC2650 (this was what I used)?

    I don think it is a problem with the launchpad design, however it could be something wrong with that particular device as it works on the CC1352. Did you try the CC1350 board as well?

    CC1352 features a new version of the sensor controller so it is not completely similar to that of the CC2650 so it would be interesting to know your results on the CC1350 board.

  • It turns out I had a second brand new, unadulterated 2650 from a mistaken order. I was going to put it on ebay, but it was easier to use that one than to extract the 1350 from the other project (I still can try the 1350 if you want me to). I do vaguely recall trying this on the 1350 at the very beginning, but opted for the 2650 because I wasn't using it. Let me know if you think its worth trying the 1350.

    Same results on the brand new 2650. I also tried pins 5&6, but I had to pull the jumper because the LED is on pin 6. This at least suggests its not a bad board. I don't know how the launchpad would differ from the sensortag in this simple setup.

  • Hi Spanky,

    If you feel like it, you could try the CC1350 LP as well, it should be more then less identical to that of the CC2650.

    I'm going to try to get my hand on a stand alone sensor to see if I can try this myself.