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

Discussion in 'Embedded Systems and Microcontrollers' started by deepikaravipati, Sep 23, 2012.

  1. deepikaravipati

    Thread Starter New Member

    Sep 23, 2012
    7
    0
    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.


    Code ( (Unknown Language)):
    1.  
    2. #include "p33Fxxxx.h"
    3.  
    4. #include <p33FJ64MC802.h>
    5. #include <i2c.h>
    6. #include <String.h>
    7.  
    8. // calculate baud rate of I2C
    9. #define Fosc (8000000)
    10. #define Fcy (Fosc/2) // no PLL
    11. #define Fsck 100000
    12. #define I2C_BRG 0x188  //((Fcy/2/Fsck)-1)
    13. #define I2C_ON  0x8000
    14.  
    15. void readFloat(float *ptr);
    16.  
    17. unsigned char SlaveAddress_read;
    18. unsigned char SlaveAddress_write;
    19.  
    20.  
    21. int main (void)
    22. {
    23. float value = 0;
    24. float temp;
    25.  
    26. I2C1CONbits.A10M = 0;
    27.  
    28. char status;
    29. unsigned char i2cbyte;
    30.  
    31. //Enable channel
    32. OpenI2C1( I2C_ON, I2C_BRG );
    33. TRSTAT=1;
    34.  
    35. SlaveAddress_read = 11010111;
    36. SlaveAddress_write = 11010110;
    37.  
    38. while (1)
    39. {
    40. readFloat(&value);
    41. }
    42.  
    43. return 0;
    44. }
    45.  
    46. void readFloat(float *ptr)
    47. {
    48. unsigned char rx_data[6];
    49.  
    50. I2C1CONbits.SEN = 1;
    51. while(I2C1CONbits.SEN);
    52.  
    53. MasterWriteI2C1(SlaveAddress_write);
    54. while (I2C1STATbits.ACKSTAT);//Return Ack Status
    55.  
    56. MasterWriteI2C1(0b10101000);
    57. while (I2C1STATbits.ACKSTAT);//Return Ack Status
    58.  
    59. I2C1CONbits.RSEN = 1;
    60. MasterWriteI2C1(SlaveAddress_read);
    61. while (I2C1STATbits.ACKSTAT);//Return Ack Status
    62.  
    63. rx_data[0] = MasterReadI2C1();
    64. I2C1CONbits.ACKDT=0;            // Set for ACk
    65. I2C1CONbits.ACKEN=1;            // Send Ack
    66. while(I2C1CONbits.ACKEN);   // wait for ACK to complete
    67.  
    68. rx_data[1] = MasterReadI2C1();
    69. I2C1CONbits.ACKDT=0;            // Set for ACk
    70. I2C1CONbits.ACKEN=1;            // Send Ack
    71. while(I2C1CONbits.ACKEN);   // wait for ACK to complete
    72.  
    73. rx_data[2] = MasterReadI2C1();
    74. I2C1CONbits.ACKDT=0;            // Set for ACk
    75. I2C1CONbits.ACKEN=1;            // Send Ack
    76. while(I2C1CONbits.ACKEN);   // wait for ACK to complete
    77.  
    78. rx_data[3] = MasterReadI2C1();
    79. I2C1CONbits.ACKDT=0;            // Set for ACk
    80. I2C1CONbits.ACKEN=1;            // Send Ack
    81. while(I2C1CONbits.ACKEN);   // wait for ACK to complete
    82.  
    83. rx_data[4] = MasterReadI2C1();
    84. I2C1CONbits.ACKDT=0;            // Set for ACk
    85. I2C1CONbits.ACKEN=1;            // Send Ack
    86. while(I2C1CONbits.ACKEN);   // wait for ACK to complete
    87.  
    88. rx_data[5] = MasterReadI2C1();
    89. I2C1CONbits.ACKDT=1;            // Set for NotACk
    90. I2C1CONbits.ACKEN=1;            // Send Nack
    91. while(I2C1CONbits.ACKEN);   // wait for ACK to complete
    92. I2C1CONbits.ACKDT=0;
    93.  
    94. StopI2C1(); //Send the Stop condition
    95. IdleI2C1(); //Wait to complete
    96.  
    97. memcpy(ptr, &rx_data, 6);
    98. }
    99.  

    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.
     
    Last edited by a moderator: Sep 23, 2012
  2. vinothmct

    New Member

    Sep 24, 2012
    14
    0
    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 .
     
  3. deepikaravipati

    Thread Starter New Member

    Sep 23, 2012
    7
    0
    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.
     
  4. vinothmct

    New Member

    Sep 24, 2012
    14
    0
    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: Oct 1, 2012
  5. deepikaravipati

    Thread Starter New Member

    Sep 23, 2012
    7
    0
    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.
     
  6. vinothmct

    New Member

    Sep 24, 2012
    14
    0
    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: Oct 2, 2012
  7. deepikaravipati

    Thread Starter New Member

    Sep 23, 2012
    7
    0
    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)
     
  8. vinothmct

    New Member

    Sep 24, 2012
    14
    0
    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.
     
  9. deepikaravipati

    Thread Starter New Member

    Sep 23, 2012
    7
    0
    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
     
  10. vinothmct

    New Member

    Sep 24, 2012
    14
    0
    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: Oct 3, 2012
  11. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,395
    1,607
    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: Oct 3, 2012
  12. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,395
    1,607
    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.
     
  13. RG23

    Active Member

    Dec 6, 2010
    301
    2
    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?????
     
  14. vinothmct

    New Member

    Sep 24, 2012
    14
    0
    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
     
  15. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,395
    1,607
    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
     
  16. deepikaravipati

    Thread Starter New Member

    Sep 23, 2012
    7
    0
    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: Oct 5, 2012
  17. vinothmct

    New Member

    Sep 24, 2012
    14
    0
    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 ?
     
  18. deepikaravipati

    Thread Starter New Member

    Sep 23, 2012
    7
    0
    Not yet!!!Don't know what to do...
     
  19. vinothmct

    New Member

    Sep 24, 2012
    14
    0
    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
     
Loading...