pic24fv32ka302 I2C connection help

Thread Starter

Cyberduke

Joined Mar 5, 2011
50
Hi guys, I have acquired the above mentioned pic and a mpu 6050 gyroscope and accelerator unit. See below all relevant documents/links for these units.

https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Datasheet1.pdf
https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Register-Map1.pdf
https://www.microchip.com/wwwproducts/en/PIC24F32KA302

Now I recently graduated from arduinos where I have used I2C on this exact gyro unit. So I know the theory. I have been struggling to implement this on MPlab using my pic. I am stuck for a while now and would really appreciate some input. I have succesfully setup the UART so that I can read results using a serial monitor on my pc.

1. I setup the I2C using the microchip code configurator.(mcc) This generated a I2c.c and I2c.h file.
2. In the I2C.h file there is some examples. And I implemented one as follows, yeah I know I literally copied and pasted and edited just what was absolutely necessary, Ill make it nice once it works)

Code:
#define MCHP24AA512_RETRY_MAX 100 // define the retry count
#define MCHP24AA512_ADDRESS 0x68 // slave device address


uint8_t MCHP24AA512_Read(
                                            uint16_t address,
                                            uint8_t *pData,
                                            uint16_t nCount)
            {
                I2C1_MESSAGE_STATUS status;
                uint8_t writeBuffer[3];
                uint16_t timeOut;
                uint16_t counter;
                uint8_t *pD, ret;

                pD = pData;

                for (counter = 0; counter < nCount; counter++)
                {

                    // build the write buffer first
                    // starting address of the EEPROM memory
                    writeBuffer[0] = (address >> 8); // high address
                    writeBuffer[1] = (uint8_t)(address); // low low address

                    // Now it is possible that the slave device will be slow.
                    // As a work around on these slaves, the application can
                    // retry sending the transaction
                    timeOut = 0;
                    while(status != I2C1_MESSAGE_FAIL)
                    {
                        // write one byte to EEPROM (2 is the count of bytes to write)
                        I2C1_MasterWrite( writeBuffer,
                                                2,
                                                MCHP24AA512_ADDRESS,
                                                &status);

                        // wait for the message to be sent or status has changed.
                        while(status == I2C1_MESSAGE_PENDING);

                        if (status == I2C1_MESSAGE_COMPLETE)
                            break;

                        // if status is I2C_MESSAGE_ADDRESS_NO_ACK,
                        // or I2C_DATA_NO_ACK,
                        // The device may be busy and needs more time for the last
                        // write so we can retry writing the data, this is why we
                        // use a while loop here

                        // check for max retry and skip this byte
                        if (timeOut == MCHP24AA512_RETRY_MAX)
                            break;
                        else
                            timeOut++;
                    }

                    if (status == I2C1_MESSAGE_COMPLETE)
                    {

                        // this portion will read the byte from the memory location.
                        timeOut = 0;
                        while(status != I2C1_MESSAGE_FAIL)
                        {
                            // write one byte to EEPROM (2 is the count of bytes to write)
                            I2C1_MasterRead( pD,
                                                    1,
                                                    MCHP24AA512_ADDRESS,
                                                    &status);

                            // wait for the message to be sent or status has changed.
                            while(status == I2C1_MESSAGE_PENDING);

                            if (status == I2C1_MESSAGE_COMPLETE)
                                break;

                            // if status is I2C_MESSAGE_ADDRESS_NO_ACK,
                            // or I2C_DATA_NO_ACK,
                            // The device may be busy and needs more time for the last
                            // write so we can retry writing the data, this is why we
                            // use a while loop here

                            // check for max retry and skip this byte
                            if (timeOut == MCHP24AA512_RETRY_MAX)
                                break;
                            else
                                timeOut++;
                        }
                    }

                    // exit if the last transaction failed
                    if (status == I2C1_MESSAGE_FAIL)
                    {
                        ret = 0;
                        break;
                    }

                    pD++;
                    address++;

                }
                return (ret);

            }
Then I call the function from my main using
Code:
  uint16_t GyroData1 = 0;

    GyroData1 = MCHP24AA512_Read(63,0x68,1);
        UartSentint(GyroData1);
I think my main problem is that I am unsure of what all the parameters are/mean. I have tried quite a bit different things etc.
now I know that the returned result will be rubbish since I am only reading 1 byte from a 16bit unsigned int(in the register of the gyro) but I am getting no result yet. Once I can read something, getting it right should be easy.

I am stuck for a while now so I would appreciate any help.
 

Thread Starter

Cyberduke

Joined Mar 5, 2011
50
Trust me if I say I did read the datasheet. That is how I got the Uart,Adc,interrupts,IO etc. working

But I2C is somehow beating me. The whole purpose of the MCC is not ease the use of this. I feel like I might be close but is still struggling.
 

be80be

Joined Jul 5, 2008
2,072
MCC There is only one problem with it that's when it don't work LOL
I just spent 5 days trying to get it to work just to figure out it was naming it's own files wrong.

If you want help you have to zip your project there is no way to help you with just a line or two of code
The MMC makes like 20 files and mplabx don't haft the time even come close to where you going wrong it build a bad file.
 

Thread Starter

Cyberduke

Joined Mar 5, 2011
50
Yeah, I believe the error is going to be something weird as that. (Or my absolute inability to work with pointers) Thank you

See attached my whole project.
 

Attachments

Thread Starter

Cyberduke

Joined Mar 5, 2011
50
The Uart is actually working.

Thank you, I will go and look further into it.
Do you maybe have a link to a guide or something where setting up with MCC is explained thoroughly?
 

Thread Starter

Cyberduke

Joined Mar 5, 2011
50
Below is the only setup options I have for I2C in MCC. So I reckon I must re read the datasheet again to set the right registers there on the right tab?



upload_2018-1-18_19-21-44.pngupload_2018-1-18_19-22-1.png
 

Thread Starter

Cyberduke

Joined Mar 5, 2011
50
So I am reading the datasheet again and this is where I get stuck.

According to what I read the I2CxSTAT<4> bit needs to be 1 in order for the bus to be in idle and ready to be used. Now this always is zero. (Figure 5-2: shows very clear)

I tried by setting the following bit I2C1CONbits.I2CEN = 1;
and also calling the initializing function from the I2C generated library from mcc.

I2C1_Initialize();

But the bus does not seem to go to idle. (I checked the clock line with my scope and it seems to stay high)
 

be80be

Joined Jul 5, 2008
2,072
I posted the one he needs "APPLICATION NOTE" i don't no that much about 6050 gyroscope and accelerator unit.
But I've messed alot with MMC and I2C You don't have it set to work on it's own.
 

be80be

Joined Jul 5, 2008
2,072
Good deal guess we both no where to look huh.
It's in the datasheet I been using the 16F18855 there a great chip but you got read them appnote's not just datasheet.
 

Thread Starter

Cyberduke

Joined Mar 5, 2011
50

shteii01

Joined Feb 19, 2010
4,644
The abovementioned document(http://ww1.microchip.com/downloads/en/DeviceDoc/70000195f.pdf) is found under the "Reference Manual" Tab on the website, not APPLICATION NOTE. Is it still called an application note then?
Anyway sorry If I offended anyone by referring to that bunch of documents all as the datasheet.
"I say what I mean.
I mean what I say."

English is not my first language. For this reason I strive to be precise when I use it.
 

Thread Starter

Cyberduke

Joined Mar 5, 2011
50
English is not my home language either. so once again apologies for errors.

So I plugged an arduino back in and looked at the I2C comms over a scope. So at this point I can probably draw an I2C conversation happening.
But when I plug the pic back in the Data line never gets pulled low to start a conversation. (Start condition). Doesn't matter what I do. I have tried soo many approaches etc.
if you look here http://ww1.microchip.com/downloads/en/DeviceDoc/70000195f.pdf then it says the P status bit (page 21) needs to be in idle then you can call a start condition. But the P status bit also never goes to idle.(HIGH) This convinces me that I am setting this up wrong.
I really would appreciate it if anyone just could maybe give me a pointer maybe of what register I am forgetting or something so I can actually start the conversation.

I don't want the complete answer, but any point in the right direction will really be appreciated.
 
Top