I2C communication with DSPIC 33F as master and Pololu MinIMU 9 v2 as slave

Thread Starter

deepikaravipati

Joined Sep 23, 2012
7
Hello everyone,
I have a problem with I2c communication in DSPIC33F. I am using DSPIC 33F as my master and pololu MinIMU 9 v2 as my slave.
http://www.pololu.com/catalog/product/1268


this is the information regarding my slave. It consists of three devices and my slave exactly is L3GD20 3-axis gyroscope
The problem is when I try to observe the readings of slave, I could see only the slave address repeatedly( I m viewing it on CRO).Except that I could not see anything else on CRO.
I m posting my program here.


Rich (BB code):
#include "p33Fxxxx.h"

#include <p33FJ64MC802.h>
#include <i2c.h>
#include <String.h>

// calculate baud rate of I2C
#define Fosc (8000000)
#define Fcy (Fosc/2) // no PLL
#define Fsck 100000
#define I2C_BRG 0x188  //((Fcy/2/Fsck)-1)
#define I2C_ON  0x8000

void readFloat(float *ptr);

unsigned char SlaveAddress_read;
unsigned char SlaveAddress_write;


int main (void)
{
float value = 0;
float temp;

I2C1CONbits.A10M = 0;

char status;
unsigned char i2cbyte;

//Enable channel
OpenI2C1( I2C_ON, I2C_BRG );
TRSTAT=1;

SlaveAddress_read = 11010111;
SlaveAddress_write = 11010110;

while (1)
{
readFloat(&value);
}

return 0;
}

void readFloat(float *ptr)
{
unsigned char rx_data[6];

I2C1CONbits.SEN = 1;
while(I2C1CONbits.SEN);

MasterWriteI2C1(SlaveAddress_write);
while (I2C1STATbits.ACKSTAT);//Return Ack Status

MasterWriteI2C1(0b10101000);
while (I2C1STATbits.ACKSTAT);//Return Ack Status

I2C1CONbits.RSEN = 1;
MasterWriteI2C1(SlaveAddress_read);
while (I2C1STATbits.ACKSTAT);//Return Ack Status

rx_data[0] = MasterReadI2C1();
I2C1CONbits.ACKDT=0;            // Set for ACk
I2C1CONbits.ACKEN=1;            // Send Ack
while(I2C1CONbits.ACKEN);   // wait for ACK to complete

rx_data[1] = MasterReadI2C1();
I2C1CONbits.ACKDT=0;            // Set for ACk
I2C1CONbits.ACKEN=1;            // Send Ack
while(I2C1CONbits.ACKEN);   // wait for ACK to complete

rx_data[2] = MasterReadI2C1();
I2C1CONbits.ACKDT=0;            // Set for ACk
I2C1CONbits.ACKEN=1;            // Send Ack
while(I2C1CONbits.ACKEN);   // wait for ACK to complete

rx_data[3] = MasterReadI2C1();
I2C1CONbits.ACKDT=0;            // Set for ACk
I2C1CONbits.ACKEN=1;            // Send Ack
while(I2C1CONbits.ACKEN);   // wait for ACK to complete

rx_data[4] = MasterReadI2C1();
I2C1CONbits.ACKDT=0;            // Set for ACk
I2C1CONbits.ACKEN=1;            // Send Ack
while(I2C1CONbits.ACKEN);   // wait for ACK to complete

rx_data[5] = MasterReadI2C1();
I2C1CONbits.ACKDT=1;            // Set for NotACk
I2C1CONbits.ACKEN=1;            // Send Nack
while(I2C1CONbits.ACKEN);   // wait for ACK to complete
I2C1CONbits.ACKDT=0;

StopI2C1(); //Send the Stop condition
IdleI2C1(); //Wait to complete

memcpy(ptr, &rx_data, 6);
}

I have been working on it since a month but could not fix the problem. I could not understand what is the problem with the code,why it is always returning the slave address but could not able to read the registers of slave. I am attaching the datasheet of dspic 33f i2c communication and that of my slave device IMU. Please help me,it's extremely urgent.
Thankyou.
 

Attachments

Last edited by a moderator:

vinothmct

Joined Sep 24, 2012
14
Haven't read much in the datasheet . Are you receiving ACK??. Call IdleI2c before starting I2C... Just a suggestion . Instead of writing start , ACK operation inside Main(). Write a seperate function for start, ACK. Code will be neat . And easier to read .
 

Thread Starter

deepikaravipati

Joined Sep 23, 2012
7
Hello Vinothmct, thankyou for your suggestion.. I' ll definitely do it. As you said I 'm not at all receiving any Ack from slave. I 'm searching for the reason why I'm not. Is it somewhere related with hardware? I mean pull ups ,level shifting or something else? I have given common power supply of 3v3(through USB port of system,regulated to 3v3) to dspic33F as well as to gyro( Vin) and pull up resistors of 4.7k .I gave power supply to Vin of gyro rather than to Vdd. Even I checked giving supply to Vdd. But the condition remained same.
 

vinothmct

Joined Sep 24, 2012
14
I really dont know . I have worked on I2C once using PIC24F and max 6956 is the I2C chip. Problems we faced was with the timing and its LED display driver. I dont think there will be any Pull up problems . Are you getting the ACK for addressing the device or not? Just probe the I2C if you have CRO to know whether the device is working .
I'll try to write up a code for this today. You write from your end . Lets see.

EDIT . Supply should be given to Vin so no problem there
 
Last edited:

Thread Starter

deepikaravipati

Joined Sep 23, 2012
7
I view the result using the CRO only...I m not receiving any acknowledgement from slave. so whtever address I 'm sending, only that is getting viewed on the CRO. The bus is getting busy with that slave address only.And I ll wrk from my end..Thankyou for your support.
 

vinothmct

Joined Sep 24, 2012
14
Is your I2cBRG value correct? What is the I2c speed you want to use? What is the clock speed?

EDIT

MasterWriteI2C1(0b10101000);
while (I2C1STATbits.ACKSTAT);//Return Ack Status

What is the need of this line?? What is 0b10101000?? I haven't read the device datasheet properly.. Just coding by keeping ur code .. BTW is there any register settings to be done for device??
 
Last edited:

Thread Starter

deepikaravipati

Joined Sep 23, 2012
7
frequency of clock-100kHz
400 KHz was too high. so I preferred 100KHz. And its corresponding hexadecimal value was mentioned in data sheet (pg..No-19-14) in 70195D(datasheet of DSPIC)
 

vinothmct

Joined Sep 24, 2012
14
What is the Fcy frequency? I mean oscillator frequency you have used? Fcy is 1/2 of oscillator frequency in 24F i believe . What abt in your controller ? There are 100 KHz hex values . We have to select depending upon Fcy no? I think you know this . Just to clear confusion i'm asking.
 

Thread Starter

deepikaravipati

Joined Sep 23, 2012
7
Even for 33F family it is Fcy=Fosc/2.
0b10101000 is the sub reigster address..
After the start condition (ST) a slave address is sent, once a slave
acknowledge (SAK) has been returned, an 8-bit sub-address is transmitted: the 7 LSb represent the actual register address while the MSb enables address auto-increment. If the MSb of the SUB field is 1, the SUB (register address) will be automatically incremented to allow multiple data read/write.
In our case first of all slave acknowledge itself is not returned.

Actually we have 6 registers intended for output..Gyro gives 16 bits per axix information..So it is mandatory to mention the sub register address
 

vinothmct

Joined Sep 24, 2012
14
Even for 33F family it is Fcy=Fosc/2.
0b10101000 is the sub reigster address..
After the start condition (ST) a slave address is sent, once a slave
acknowledge (SAK) has been returned, an 8-bit sub-address is transmitted: the 7 LSb represent the actual register address while the MSb enables address auto-increment. If the MSb of the SUB field is 1, the SUB (register address) will be automatically incremented to allow multiple data read/write.
In our case first of all slave acknowledge itself is not returned.

Actually we have 6 registers intended for output..Gyro gives 16 bits per axix information..So it is mandatory to mention the sub register address
Yes read the device datasheet . Halfway through the code. Will post as soon as i complete

Where is the subaddress specified?? I cant find it in datasheet. Are you sure that is subadrees

I dont think this will work straight away . Lot need to be written in control register etc. Datasheet aint clear/or i dont understand. Let me try. Have a look at this you might get some ideas
http://forums.parallax.com/showthread.php?142428-I2C-Interfacing&

Dont fail to inform me when u get the desired result and i will post this query on microchip website . An expert might help
 
Last edited:

ErnieM

Joined Apr 24, 2011
8,377
Getting the ACK from the slave is essential for any I2C transaction. The good news is you have a scope to check the signals. The addresses you have for SlaveAddress_read and SlaveAddress_write look correct, but sometimes the MC library takes this as a 7 bit entity (I've not used the ones for your device). so check again what is going out. If possible, could you post a picture of the scope screen for the address output so we can all check each bit for correctness?

Once you get an ACK, to read a device you start by writing to it. This confused me to no end till I understood it. A read goes like this:

START
Write address (write)
ACK (from slave)
Write register (sub) address <-- THIS tells the slave which register to start the read from
ACK (from slave)
RESTART
Write address (read)
ACK (from slave)
Read data
ACK (from master)
Read data
ACK (from master)
...
Read data
NACK (from master)
STOP

This is contained in Table 15. Transfer when master is receiving (reading) multiple bytes of data from slave
 
Last edited:

ErnieM

Joined Apr 24, 2011
8,377
And while I think of it... I2C devices can get confused and lock up. When I'm debugging and halt the PIC mid I2C transaction I have to power off then power on the I2C device, as it can be "stuck" in some weird mode, such as it's doing an ACK so it has the bus in the wrong state. The PIC gets confused and can't start as the bus is not free.

You can also clear this up by automatically by clocking the I2C clock line several times at power-up as part of the init sequence.
 

RG23

Joined Dec 6, 2010
304
my program worked before absolutely fine
Now I am having a critical issue

when the master requests the data from slave and check

btfss PIR1,3 in the slave program

the interrupt is generated

that is, the slave recognizes its address and read mode

but when i transmit the data from master to slave and check

btfss PIR1,3 in the slave program

the interrupt is not generated

what could be the reason?????
 

vinothmct

Joined Sep 24, 2012
14
Is the sub address specified in the code right?

This one is highly confusing for me ...

BTW only thread starters can attach files . Have re wrote the code . Cant attach it here
 

ErnieM

Joined Apr 24, 2011
8,377
vinothmct, are the files for deepikaravipati? If so, hit the GO ADVANCED button on the below the reply box, then that page has the attachment manager.


You don't need to start the thread to attach files
 

Thread Starter

deepikaravipati

Joined Sep 23, 2012
7
sorry for the late reply vinoth...
In the data sheet of L3GD20, pg.no 29/44 he gave the addresses of all the registers....
OUT_X_L r 28 010 1000 output
OUT_X_H r 29 010 1001 output
OUT_Y_L r 2A 010 1010 output
OUT_Y_H r 2B 010 1011 output
OUT_Z_L r 2C 010 1100 output
OUT_Z_H r 2D 010 1101 output
This is my first time to work with the Programmable device.. I really could not understand what to do with the slave's control register...I thought like if we could set the micro controller's control registers,it's okay..But is there really something to worry about the control registers of the gyro?
And I have posted the problem already in Microchip forum and Pololu forums...
 
Last edited:

vinothmct

Joined Sep 24, 2012
14
sorry for the late reply vinoth...
In the data sheet of L3GD20, pg.no 29/44 he gave the addresses of all the registers....
OUT_X_L r 28 010 1000 output
OUT_X_H r 29 010 1001 output
OUT_Y_L r 2A 010 1010 output
OUT_Y_H r 2B 010 1011 output
OUT_Z_L r 2C 010 1100 output
OUT_Z_H r 2D 010 1101 output
This is my first time to work with the Programmable device.. I really could not understand what to do with the slave's control register...I thought like if we could set the micro controller's control registers,it's okay..But is there really something to worry about the control registers of the gyro?
And I have posted the problem already in Microchip forum and Pololu forums...
I'm not an expert either that is why i have an active interest :p
Have you got any replies . Are you able to fix the issue ?
 

vinothmct

Joined Sep 24, 2012
14
Sorry i was quite with work couldn't work on this . Will try on friday . I have posted the zip file which contains API for i2c . Main is the file i tried to work on . I just kept your code as template .. Look into i2c_good file . It was taken from PIC forum . It is quite good . And it works . Try adding a few asm("nop") b/w start, read etc . DO intimate me if there is any errors in those files
 

Attachments

Top