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.

Problem with mpu6050.c library

Regarding this post: http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/t/315587.aspx

        //
        // Status register was read, check if reset is done before proceeding.
        //
        case MPU6050_STATE_INIT_WAIT:
        {
            //
            // Check the value read back from status to determine if device
            // is still in reset or if it is ready.  Reset state for this
            // register is 0x40, which has sleep bit set.
            //
            if(psInst->pui8Data[0] != MPU6050_PWR_MGMT_1_SLEEP)
            {
                //
                // Device still in reset so begin polling this register.
                //
                psInst->uCommand.pui8Buffer[0] = MPU6050_O_PWR_MGMT_1;
                I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
                         psInst->uCommand.pui8Buffer, 1, psInst->pui8Data, 1,
                         MPU6050Callback, psInst);
            }
            else
            {
                //
                // Device is out of reset, move to the idle state.
                //
                psInst->ui8State = MPU6050_STATE_IDLE;
            }
            break;
        }

When t refer to the mpu9150, and i change the mpu6050.c lib to this one:

        case MPU6050_STATE_INIT_WAIT:
        {
            //
            // Check the value read back from status to determine if device
            // is still in reset or if it is ready.  Reset state for this
            // register is 0x40, which has sleep bit set.  Device may also
            // respond with an address NACK during very early stages of the its
            // internal reset. Keep polling until we verify device is ready.
            //
            //
            if((psInst->pui8Data[0] != MPU6050_PWR_MGMT_1_SLEEP) ||
                (ui8Status == I2CM_STATUS_ADDR_NACK))
            {
                //
                // Device still in reset so begin polling this register.
                //
                psInst->uCommand.pui8Buffer[0] = MPU6050_O_PWR_MGMT_1;
                I2CMRead(psInst->psI2CInst, psInst->ui8Addr,
                         psInst->uCommand.pui8Buffer, 1, psInst->pui8Data, 1,
                         MPU6050Callback, psInst);

                //
                // Intentionally stay in this state to create polling effect.
                //
            }
            else
            {
                //
                // Device is out of reset, move to the idle state.
                //
                // psInst->ui8State = MPU6050_STATE_IDLE;
				
				                //
                // Device is out of reset, bring it out of sleep mode.
                //
                psInst->uCommand.pui8Buffer[0] = MPU6050_O_PWR_MGMT_1;
                psInst->uCommand.pui8Buffer[1] = MPU6050_PWR_MGMT_1_CLKSEL_XG;
                I2CMWrite(psInst->psI2CInst, psInst->ui8Addr,
                          psInst->uCommand.pui8Buffer, 2, MPU6050Callback,
                          psInst);

                //
                // Update state to show we are modifing user control and
                // power management 1 regs.
                //
                psInst->ui8State = MPU6050_STATE_INIT_PWR_MGMT;
				
            }
            break;
        }

But i dont actually understand why and also the state machine. Can anybody help me, i posted many questions but nobody answers me!

Please help me!

  • Hi,

    I noticed your old thread, but not read; instead read this one.

    There is an internal difference between the two chips - 9150 has an internal ak8975 magnetometer embedded - and of coarse a lot of software for the state machine to reset/init/read/write to both sub-modules (accel+magneto).

    You may find out yourself those differences if you use a tool to "make a diff" between the two files - mpu6050.c and mpu9150.c (a good tool to do that is gvim). And i do not suggest to make modifications to one file to behave like the other one. Better to read/understand the user manual of those sensors - I know takes time, but to understand and have the full control, you must do.

    Petrei

  • I can perhaps help at a high level with the state machine.

    When the library performs a write or read from the sensor it can sometimes require several steps and several unique I2C transactions.  Each unique i2c transaction is a substate.  The state transitions only occur in the callback so that it is assured that the previous i2c transaction is complete before starting the next transaction. 

    To paraphrase:

    First write these registers (started in the init function)

    When done (in callback), queue up a write to the next set of registers. This write not generally consecutive registers to previous step.

    When done (in callback), queue up another write to next set of registers. Also generally not consecutive.

    repeat until all INIT sub states have been done and all INIT registers are written with the new values.

    When complete with all registers writes (still in callback). set state to idle and if != null call the application level callback.

  • Thanks Petrei, but when i modify the mpu6050.c the program works, otherwise it fails. Do you know the reason?

    And how about this post? 

    http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/t/315587.aspx

  • , you  mean:

    1. First write these registers (started in the init function) ==> implemented in MPU6050Init

     

    2. When done (in callback), queue up a write to the next set of registers. This write not generally consecutive registers to previous step.

    When done (in callback), queue up another write to next set of registers. Also generally not consecutive.

    repeat until all INIT sub states have been done and all INIT registers are written with the new values.

    When complete with all registers writes (still in callback). set state to idle and if != null call the application level callback.

    ==> Implemented in MPUCallBack State Machine

    Is that right?

  • Yes but all of that is still inside the library <sensor>.c file not your application file.

    wrapped around this is another callback layer where the sensor layer can call the callback you provide to the sensor layer.

    at the bottom is i2c hardware layer.  It just knows bytes.  It sends/receives a collection of bytes (one I2C start to stop possibly with repeated starts in the middle)  This i2c layer has its own state machine and interrupt handler (callback). when i2c is done it calls the sensor layer callback.

    In the middle is the sensor layer which is what is what my previous post was about.  It calls down to the i2c layer and is called from the app layer.  the sensor layer passes a pointer to its callback to the i2c layer.  sensor layer receives a pointer the app layer (your application) callback.  A single sensor layer operation might result in multiple i2c layer transactions and multiple calls between the i2c layer and the sensor layer callback.

    Your application layer calls sensor layer.  app layer provides a callback down to the sensor layer.  when sensor layer is done it calls the app layer callback that was provided.