The Web Design Group

... Making the Web accessible to all.

Welcome Guest ( Log In | Register )

 
Reply to this topicStart new topic
> Can't get I2C to work on PIC32 (“skips” bytes/hangs)
ysl12
post Nov 26 2016, 04:44 AM
Post #1





Group: Members
Posts: 2
Joined: 11-October 16
Member No.: 24,882



I am working on a PIC32-MAXI-WEB development board from Olimex that I'd like to have communicating with an Invensense MPU-6050 6DOF accelerometer/gyro. By modifying an demo from Olimex I managed to get the pic communicating.

I started working on a project for which I created a new project(in IDE) as I did not need/want the FreeRTOS kernel that the demo is built on. However I can't make the same I2C code work there. I get some output, but not what I should get.

Helper functions from the Olimex DEMO:
CODE
BOOL StartTransfer( BOOL restart )
{
    I2C_STATUS  status;

    // Send the Start (or Restart) signal
    if(restart)
    {
        I2CRepeatStart(I2C2);
    }
    else
    {
        // Wait for the bus to be idle, then start the transfer
        while( !I2CBusIsIdle(I2C2) );

        if(I2CStart(I2C2) != I2C2)
        {
            DBPRINTF("Error: Bus collision during transfer Start\n");
            return FALSE;
        }
    }

    // Wait for the signal to complete
    do
    {

        status = I2CGetStatus(I2C2);

    } while ( !(status & I2C_START) );

    return TRUE;
}


BOOL TransmitOneByte( UINT8 data )
{
    // Wait for the transmitter to be ready
    while(!I2CTransmitterIsReady(I2C2));

    // Transmit the byte
    if(I2CSendByte(I2C2, data) == I2C_MASTER_BUS_COLLISION)
    {
        DBPRINTF("Error: I2C Master Bus Collision\n");
        return FALSE;
    }

    // Wait for the transmission to finish
    while(!I2CTransmissionHasCompleted(I2C2));

    return TRUE;
}

void StopTransfer( void )
{
    I2C_STATUS  status;

    // Send the Stop signal
    I2CStop(I2C2);


    // Wait for the signal to complete
    do
    {
        status = I2CGetStatus(I2C2);

    } while ( !(status & I2C_STOP) );
}

My code:
CODE
int I2C_CLOCK_SPEED = 400000;

int actualClock;

// Configure Various I2C Options
I2CConfigure(I2C2, 0);

// Set Desired Operation Frequency
actualClock = I2CSetFrequency(I2C2, GetPeripheralClock(), I2C_CLOCK_SPEED);
if ( abs(actualClock-I2C_CLOCK_SPEED) > I2C_CLOCK_SPEED/10 ) {
    return -1;
}

// Enable the module
I2CEnable(I2C2, TRUE);

BYTE ADDR = 0x68<<1;

BIT WRITE = 0;
BIT READ = 1;

BYTE tmp;

StartTransfer(FALSE); // Read power management register

TransmitOneByte(ADDR|WRITE);
TransmitOneByte(0x75);

StartTransfer(TRUE);

TransmitOneByte(ADDR |READ);
I2CReceiverEnable(I2C2, TRUE);
while(!I2CReceivedDataIsAvailable(I2C2));
I2CAcknowledgeByte(I2C2, FALSE);
tmp = I2CGetByte(I2C2);

StopTransfer();

With a logic analyzer I can see that it seems to drop the address and send just the second byte of the three. It also fails to send the stop bit/return the bus to idle:
IPB Image
IPB Image
It should not be a hardware problem as the original demo works. I am using the xc32 compiler and MPLAB X IDE.
User is offlinePM
Go to the top of the page
Toggle Multi-post QuotingQuote Post
hotenda.com
post Feb 15 2017, 04:35 AM
Post #2





Group: Members
Posts: 1
Joined: 15-February 17
Member No.: 26,314



http://www.hotenda.com/product-tags/MPU-6050.html
This page Is there information you want?
What are the MPU-6050 products?
User is offlinePM
Go to the top of the page
Toggle Multi-post QuotingQuote Post

Reply to this topicStart new topic
3 User(s) are reading this topic (3 Guests and 0 Anonymous Users)
0 Members:

 



- Lo-Fi Version Time is now: 28th April 2017 - 11:04 AM