Microchip

 I2C Master on PIC24FJ64 Series

Change Page: 1234 > | Showing page 1 of 4, messages 1 to 20 of 64
Author Message
jliu83

  • Total Posts : 15
  • Reward points : 0
  • Joined: 6/20/2007
  • Location: 0
  • Status: offline
I2C Master on PIC24FJ64 Series Thursday, July 26, 2007 10:35 AM (permalink)
0
    Hi all, seems like a lot of people have problems with the I2C module on the PIC24FJ64 series of chips.  The COLLISION BIT seems to go high when ever a start condition is asserted.

    I just got off the phone with microchip support.  The solution is in the A3 silicon errata.  Here is the link:

http://ww1.microchip.com/downloads/en/DeviceDoc/80316b.pdf

    On page 3, under I2C module it says:

In Master mode using I2C1, after a device Reset, a bus collision may occur instead of a Start bit transmission if the SDA1 line is not driven low prior to sending the Start bit. Transmissions after the first low-to-high transition of SDA1 will occur correctly.

In Slave mode using I2C1, the device may not Acknowledge the first packet sent after a device Reset. This occurs if the SDA1 line is not pulled low prior to a data packet being sent to the device. In this case it will return a NACK instead of an ACK. The device will correctly respond to packets following the first low-to-high transition of SDA1
after a device Reset. I2C2 operates as expected and does not exhibit
this issue.

Work around
In Master mode, configure the SDA1 pin as an output and drive it low and then high prior to sending a Start bit. Note that this action could appear to be a Start bit to an I2C slave device if the SCL1 pin is not driven low prior to driving SDA1 low. In Slave mode, the master must either pull the SDA line low, then high again, prior to sending the packet to the device or resend the first packet.

    So there.  I have tried it and it works.  Simply put in the following lines.

LATBbits.LATBx = 0;   //where LATBx = the SDAx pin
LATBbits.LATBx = 1;

    This must be done AFTER the module is enabled, and your TRISB must be set such that the SDAx pin is configured as an output.

    Reply if you got any questions!

-J
 
#1
    payneshouse

    • Total Posts : 1
    • Reward points : 0
    • Joined: 7/26/2007
    • Location: 0
    • Status: offline
    RE: I2C Master on PIC24FJ64 Series Thursday, July 26, 2007 2:58 PM (permalink)
    0
    Hey J,

    I've been stuck on the I2C problem for sometime now.  I tried the new workaround and it still doesn't work.  Would it be possible to see your code?  How do you drive SDA1 low after enabling the I2C module? 
    <message edited by payneshouse on Thursday, July 26, 2007 3:01 PM>
     
    #2
      wingliet

      • Total Posts : 3
      • Reward points : 0
      • Joined: 8/9/2007
      • Location: 0
      • Status: offline
      RE: I2C Master on PIC24FJ64 Series Saturday, August 11, 2007 8:15 PM (permalink)
      0
      I face the similar problem.
      i tried varios way to set the prot pin.
      can any one post the correct way to solve this problem?

      thanks in advance
       
      #3
        jliu83

        • Total Posts : 15
        • Reward points : 0
        • Joined: 6/20/2007
        • Location: 0
        • Status: offline
        RE: I2C Master on PIC24FJ64 Series Friday, September 21, 2007 11:01 AM (permalink)
        0
        Sorry for the late post, didn't check the forums for a long time.

        Here is the solution:

        On a PIC24FJ64002, with the I2C set up on primary pin set (pin 17-18):
        To initiate the I2C I do this:

        I2C1CON = 0xD200;
        I2C1BRG = 155;      //16 Mhz clock, with PPL
            LATBbits.LATB9 = 0;            //from Errata, the bug on the chip needs these two lines
            LATBbits.LATB9 = 1;

        That's the initiation.  Now to see if it works do the following:
        Check your I2C1STAT registers, it should read 0x0010, which means the channel is idle, and is ready to assert a start condition.  If the register reads 0x0000, means something is wrong with the circuitry (no pull ups?, or an IC is forcing it to be high, or something).  If it reads a 0x00080, then the line is low, and its being grounded by something.  Remember the line should be high all the time.

        If the I2C1STAT register reads 0x0010, then you can assert your starting condition:

                        I2C1CONbits.PEN = 1;
                        if((I2C1STATbits.S == 0) && (I2C1STATbits.P == 1))
                            I2C1CONbits.SEN = 1;

        Check the status of the bus to make sure it is idle, then send the start condition.  Check your buses on the scope.  If it is reading 0 volts, then your I2C bus works.  Otherwise check the I2CSTAT register, it should reads 0x0080, meaning the master has asserted a start.

        Reply if you are still having problems.

        -J

         
        #4
          botbuilder

          • Total Posts : 3
          • Reward points : 0
          • Joined: 9/29/2007
          • Location: 0
          • Status: offline
          RE: I2C Master on PIC24FJ64 Series Saturday, September 29, 2007 3:20 PM (permalink)
          0
          Hello,


          I have tried this workaround and am still having problems.


          I am using a PIC24FJ16GA002.


          I have both I2C units set up and on the same bus along with an I2C EE. Both are set up to act as both master and slave, I also have a PICkit Serial on the bus. This arrangement is only for development / testing – I do not intend to have a multi master environment. I do however need two separate I2C masters so I can't simply use I2C2. All bus traffic is controlled (manually initiated and monitored on a scope) to ensure no bus contention.


          In this setup I2C2 works perfectly – that is it can act as a master and access either I2C1 or the EE as a slave. It also responds correctly as a slave to the PICkit Serial. I2C1 works correctly as a slave and can be accessed from either the PICkit Serial or I2C2. The problem I am having is that I can not get I2C1 to work as a master.


          I have tried numerous ways of implementing the workaround to include:
          Toggling the SDA line in the I2C1 init code both before and after enabling I2C1
          Toggling the SDA line external to the chip (using the PICkit Serial to access the EE) both before and after enabling I2C1.
          Pulling the SDA line low manually with a switch on the dev PCB.
          And other combinations such as Toggle, enable, toggle, disable, toggle, enable


          All these result in the same reported bus collision when I try and send a start with I2C1.


          I have a scope on the bus and can verify that it is not busy. Also, I can continue to use I2C2 as a master after I2C1 reports the collision.


          Code for I2C1 and I2C2 is identical. Only thing that changed is the register names.


          I am guessing this is a variant of the errata and possible unique to the PIC24FJ16GA002. Any advice or ideas would be much appreciated.


          Thanks
           
          #5
            botbuilder

            • Total Posts : 3
            • Reward points : 0
            • Joined: 9/29/2007
            • Location: 0
            • Status: offline
            RE: I2C Master on PIC24FJ64 Series Sunday, September 30, 2007 12:09 PM (permalink)
            0
            After a good deal more testing and frustration, this is my take on the problem:


            The I2C modules come out of reset with both the S and P (start and stop) set to 0. This is expected as when first coming out of reset, the state of the bus is unknown.


            Interestingly enough, it seems that I2C1 and I2C2 have different criteria for detecting a bus collision. It looks like I2C1 looks to see if the P (stop) bit is set whereas I2C2 looks to see if the S (start) bit is clear. This allows I2C2 to correctly function because it sees the S bit clear and determines it is safe to transmit. The I2C1 sees that the P (stop) bit is clear and thinks the bus is busy because the last thing on the bus was not a stop.


            I have tested this theory with my setup and it holds. I2C2 will correctly act as both as master and a slave from reset. From reset, I2C1 can act as a slave but can not act as a master until it sees a valid start/stop on the bus. In my previous post, I stated that I could not get I2C1 to work, what I changed to get it past the initial bus collision problem was to send a full start/stop on the buss. It is worth noting that I2C1 did not have to participate, any start/stop on the bus after I2C1 was enabled would set the P bit so that it could transmit as a master. I have had no problems with I2C1 after it sees a start/stop on the bus.


            I can suggest two workarounds for the problem:
             
                1) If used in a multi master environment, have another master initiate communication or generate traffic on the bus.
                2) If I2C1 must be used as a single master, tie to other port pins to the I2C bus and bit bang the initial start stop.


            I have done limited testing on both of these and gotten them to work. Unfortunately neither one will work for my application. I have two 24Fs talking to each other with one I2C – so neither can start traffic. The other I2C on each 24F is used as a single master to control I2C devices. I also don't have the pins to spare to dedicate a pair to giving the initial start/stop.


            It seems that the work around given earlier in this thread and in the errata should work to accomplish the same thing. However, it seems that the I2C1 module must be enabled before it will detect the start/stop and that once it is enabled, writes to the port latches have no effect so nothing I try in code will result in the P bit being set. The errata suggests that if you bring SDA low with the latch prior to enabling I2C1 it will fix the problem – this does not work for me.


            As a note, I have tried all of this on multiple PIC24FJ16GA002s and a PIC24FJ64GA002 as well and gotten the same results.


            Any help or advise would be appreciated.


             
            #6
              houta69

              • Total Posts : 275
              • Reward points : 0
              • Joined: 8/4/2007
              • Location: Georgia, USA
              • Status: offline
              RE: I2C Master on PIC24FJ64 Series Monday, October 08, 2007 5:23 PM (permalink)
              0

              After a good deal more testing and frustration, this is my take on the problem:

               
              Very nice write up botbuilder. I am also *trying* to work with the I2C1 module on a PIC24FJxxGA002. After many trials and tribulations I have got nowhere. The I2C2 module works like a champ, but switch pins, change the register names and nada. The work around in the silicon errata has no effect and in my case bit banging the start / stop conditions onto the bus via two additional pins as you suggested failed to jump start the module as well.
               
              I was wondering if you ever created a support ticket for this? I think your assesment of this being a variant of the errata unquie to the 002's may be right on target. Thanks
               
              #7
                botbuilder

                • Total Posts : 3
                • Reward points : 0
                • Joined: 9/29/2007
                • Location: 0
                • Status: offline
                RE: I2C Master on PIC24FJ64 Series Wednesday, October 10, 2007 6:24 AM (permalink)
                0
                I guess it is a bit comforting to know someone else is having the same problem, though it does not make it any easier to solve.  I can offer some advice on what I have reliably working.
                 
                I have I2C1 working as a master but it still requires external stimulus to initialize it.  I use one additional pin to do this.  This is the sequence I use:
                 
                Hardware setup:
                Connect an additional pin to SDA1 (I use pin 18 but any I/O pin should work)
                    
                Software setup:
                Init the I2C1 module and enable it
                Clear the additional pin latch (so it will drive 0 when set as output)
                Configure the additional pin as an output (TRIS)
                Wait about 50us
                Configure the additional pin as an input (TRIS)
                 
                The last step is important, when you configure the pin as an input the external pull-ups will bring SDA high and set the stop bit in I2C1.  Also, as an input the additional pin will not interfere with bus traffic.  SCL should remain pulled high through the entire procedure.
                 
                After this procedure, the stop bit is set in I2C1 and it works as a master.  I have been using this procedure for several days of development and have had no problems with it.
                 
                Note, this start up procedure may confuse I2C slave devices.  I send a start / stop from the I2C1 master as part of initialization (after the additional pin toggle) to eliminate this problem.  The slave devices I use will see this and reset their internal state machines.
                 

                As a side note if you are using a dev board, make sure nothing else is driving the pins.  I seem to remember needing to modify the 28 pin dev board when I was using it to free up many of the pins – I unfortunately don’t remember if I modified the I2C1 pins or not.
                 
                Hope this helps.
                 
                In answer to your question, I have not opened a support ticket.
                 
                 
                #8
                  JVB

                  • Total Posts : 2
                  • Reward points : 0
                  • Joined: 10/19/2007
                  • Location: 0
                  • Status: offline
                  RE: I2C Master on PIC24FJ64 Series Friday, October 19, 2007 6:51 PM (permalink)
                  0
                  Thanks to everybody who posted on this thread.  Using the ideas here I used the following code:
                   I2C1CONbits.I2CEN=0;  //I2C Disabled
                     I2C1BRG = 155;      
                     TRISBbits.TRISB9= 0; //PB9 is output
                     LATBbits.LATB9 = 0; 
                     Nop();
                     I2C1CON = 0xD200;    //Enable While PB9 is low
                     Nop();
                     TRISBbits.TRISB9= 1; //PB9 is set to input 
                     LATBbits.LATB9 = 1;  // makes no difference ??
                     I2C1ADD=0;
                     I2C1MSK=0;
                   
                  It works for me so far and seems to be a lot simpler than jumpering another pin.  I think I'll start checking here (the forum) first when I run into something like the I2C1 problem that seems to make no sense at all.
                   
                  #9
                    labegf

                    • Total Posts : 4
                    • Reward points : 0
                    • Joined: 11/18/2007
                    • Location: 0
                    • Status: offline
                    RE: I2C Master on PIC24FJ64 Series Sunday, November 18, 2007 3:45 PM (permalink)
                    0
                    I was following the discussion and I have just implemented the last suggestion (JVB's suggestion). As result, it didn't work. The difference is that I'm using the alternative pins to I2C1 (pins 14 and 15 of the PIC26FJ64GA002).

                    When I run the code, the I2C doesn't work. But, if I just force the SDA to GND, the I2C1 starts working perfectly. It works like a "start" to the peripheral.

                    Note: the I2C2 module works perfectly with the same code (just changing the registers name).

                    I have already many solutions, but none of them worked.

                    By now, just the forced ground in the SDA pin makes it work.
                     
                    #10
                      Volkiman

                      • Total Posts : 6
                      • Reward points : 0
                      • Joined: 9/17/2007
                      • Location: Germany
                      • Status: offline
                      RE: I2C Master on PIC24FJ64 Series Tuesday, November 27, 2007 1:31 AM (permalink)
                      0
                      I also have a problem with my I2C1-Module on the Pic24FJ128GA006. I want to use it as a Slave. With the following code I init the module:

                      {
                         //clear Flag
                         _SI2C1IF = 0;
                         //Set Priority
                         _SI2C1P0 = 1;
                         _SI2C1P1 = 1;
                         _SI2C1P2 = 0;
                         I2C1ADD = 0xB1; //Use with or without the R/W-Bit?? (without would mean it's 0xB0)
                         I2C1BRG = 45;
                         I2C1CON = (I2C_EN | I2C_IDLE_CON | I2C_SLW_EN | I2C_GC_EN | I2C_ACK | I2C_ACK_DIS);
                          //Interrupt Enable
                          _SI2C1IE = 1;
                      }

                      If I use the SlavegetsI2C1-function of the c30-lib i receive the char's. But I want to do it with an ISR that looks like this:
                      void _ISR _SI2C1Interrupt()
                      {
                         unsigned char dummy;
                         dummy = I2C1RCV;
                      }

                      But it never steps in the ISR. Does anybody know a reason? Is there any bit that is not set?

                      THX Volkiman

                      I must correct myself: with the SlavegetsI2C1-function the received char's are not correct.  The Baudrate-Settings are also checked.
                      <message edited by Volkiman on Tuesday, November 27, 2007 4:00 AM>
                       
                      #11
                        sjo

                        • Total Posts : 49
                        • Reward points : 0
                        • Joined: 2/22/2006
                        • Location: UK
                        • Status: offline
                        RE: I2C Master on PIC24FJ64 Series Tuesday, November 27, 2007 7:57 AM (permalink)
                        0

                        I can also confirm the workaround in the errata works for the default I2C1 config, but as labegf has found it does not work for the alternate config.

                        Cheers
                        sjo
                         
                        #12
                          labegf

                          • Total Posts : 4
                          • Reward points : 0
                          • Joined: 11/18/2007
                          • Location: 0
                          • Status: offline
                          RE: I2C Master on PIC24FJ64 Series Sunday, December 09, 2007 2:31 PM (permalink)
                          0
                          Hello guys.

                          I was using the PIC24FJ64GA002 and just the I2C2 was working. To use the I2C1, it was necessary to force a low level (0V) in the SDA pin manually (externally). I've tried many solutions to do the I2C1 run using just software changes, like config the pin to output and LAT = 0, but it didn't work.

                          Now, I'm trying to migrated to PIC24FJ16GA004 and both I2C's aren't working. Both I2C's require an "external help" (0V in SDA) to work.

                          Does someone can explain me what's happening?

                          Thanks
                           
                          #13
                            labegf

                            • Total Posts : 4
                            • Reward points : 0
                            • Joined: 11/18/2007
                            • Location: 0
                            • Status: offline
                            RE: I2C Master on PIC24FJ64 Series Tuesday, December 11, 2007 6:22 PM (permalink)
                            5
                            After many tests, I discovered that the following initialization works. But, I just got it using a 10K pull-up resistors in the data and clock wires. The previous 4K7 were resulting in any unexpected behavior that I'm not able to explain.

                            void DrvI2C__Init (void)
                            {
                                TRISBbits.TRISB9= 0; //PB9 is output (SDA pin)
                                LATBbits.LATB9 = 0;
                                Nop();
                                I2C1BRG = 39;
                                I2C1CON = 0xD200;    //Enable While PB9 is low
                                I2C1ADD=0;
                                I2C1MSK=0;
                            }
                             
                            #14
                              mmullins_9999

                              • Total Posts : 28
                              • Reward points : 0
                              • Joined: 4/28/2007
                              • Location: The great state of Texas
                              • Status: offline
                              RE: I2C Master on PIC24FJ64 Series Wednesday, December 26, 2007 10:33 AM (permalink)
                              0
                              Thanks labegf!  I've been having trouble with the 2nd I2C port on a PIC24FJ64GA002 (Revision 0x3003), and this fix worked for me.  At least I got past the initial problem.  However, something is still partially pulling down both lines.

                              The errata that claims this is a problem with I2C1 only is wrong, and the work-around they suggest didn't work for me.
                               
                              #15
                                mmullins_9999

                                • Total Posts : 28
                                • Reward points : 0
                                • Joined: 4/28/2007
                                • Location: The great state of Texas
                                • Status: offline
                                RE: I2C Master on PIC24FJ64 Series Sunday, December 30, 2007 10:23 AM (permalink)
                                0
                                Just to follow up on this, it quit working when I removed the scope probe from SDA2.  Like some people, it only behaves when you are watching.  I tacked a 10 pF capacitor from SDA2 to GND, and that 'fixed' it.  My guess is that you need to have the pin low when you configure I2C2 (or I2C1).  Botbuilder's suggestion to use another output pin to pull the SDA pin low is probably the best work-around.  I hate to add capacitance to these lines.

                                I think all of the different results are due to different clock speeds, different pull-up resistors, and bus capacitance.  What's the RC time-constant of your SDA line compared to the time it takes to configure the I2C port? 

                                I hope that Microchip fixes this in the next revision.  I've wasted a huge amount of time on this.
                                 
                                #16
                                  Builty

                                  • Total Posts : 47
                                  • Reward points : 0
                                  • Joined: 7/18/2007
                                  • Location: 0
                                  • Status: offline
                                  RE: I2C Master on PIC24FJ64 Series Tuesday, January 01, 2008 6:23 PM (permalink)
                                  0
                                  Thanks labegf, this helped me too. I was having some problems with the I2C2 master on a 64GA004. I was finding that if I did a full power off/on then the I2C slave eeprom would work fine, but if I gave it a reset via the ICD2 then it would not function correctly (returns 0 for all reads).

                                  Setting SDA to an output and driving it low before enabling the module has made it a whole lot better. Not quite perfect yet though, maybe when I hit Stop on the ICD2 it leaves it in yet another unhealthy state.
                                   
                                  #17
                                    sixties

                                    • Total Posts : 5
                                    • Reward points : 0
                                    • Joined: 8/28/2007
                                    • Location: 0
                                    • Status: offline
                                    RE: I2C Master on PIC24FJ64 Series Thursday, January 10, 2008 3:05 AM (permalink)
                                    0
                                    Thank you labegf !

                                    I Also use PIC24FJ64GAA02 with I2C1 on I/O #14 and #15 ; and the change from 2.2k pull-up to 10k pull-up solves the problem !
                                     
                                    Edit : It also needs a 15pF capacitor between SDA and GND to work without oscilloscope ;-)

                                    void init_I2C(void)
                                    {
                                       TRIS_I2C_SCL=IN;
                                       TRIS_I2C_SDA=IN;
                                    //Silicon Errata
                                       TRIS_I2C_SDA=OUT;
                                       WR_I2C_SDA=0;
                                    //Disables the I2Cx module
                                       I2C1CONbits.I2CEN=0;   
                                    //I2C bus clock => I2CxBRG = ( Fcy/Fscl - Fcy/10.000.000 ) - 1
                                    //I2C bus clock => Fscl = 1/( (I2CxBRG+1)/Fcy + (1/10.000.000) )
                                       I2C1BRG=0x0026;     //394kHz @ 16MHz
                                      
                                       I2C1CON=0b0000000000000000;
                                           //I2CEN=0 => Disables the I2Cx module
                                           //I2CSIDL=0 => Continue module operation in Idle mode
                                           //SCLREL not used (slave) => SCLx Release Control bit
                                           //IPMIEN=0 => IPMI Support mode disabled
                                           //A10M=0 => I2CxADD is a 7-bit slave address   
                                           //DISSLW=0 => Slew rate control enabled => 400kHz
                                           //SMEN=0 => Disable SMBus input thresholds
                                           //GCEN not used (slave) => General call address disabled
                                           //STREN not used (slave) = Disable software or receive clock stretching
                                           //RCEN=0 => Receive sequence not in progress
                                       I2C1STAT=0b0000000000000000;
                                           //Clear BCL: Master Bus Collision Detect bit
                                           //Clear IWCOL: Write Collision Detect bit
                                           //Clear I2CPOV: Receive Overflow Flag bit

                                    //Enables the I2Cx module and configures the SDAx and SCLx pins as serial port pins
                                       I2C1CONbits.I2CEN=1;   
                                    }
                                    <message edited by sixties on Thursday, January 10, 2008 3:46 AM>
                                     
                                    #18
                                      houta69

                                      • Total Posts : 275
                                      • Reward points : 0
                                      • Joined: 8/4/2007
                                      • Location: Georgia, USA
                                      • Status: offline
                                      RE: I2C Master on PIC24FJ64 Series Thursday, March 27, 2008 9:52 AM (permalink)
                                      0
                                      Just an FYI for users of the PIC24FJ64GA004 family of chips. Microchip just released a new errata with a revision to the IC21 bus collision problem. They are now recommending that a second pin be used to drive the SDA1 line low for 150ns after enabling the module which matches what botbuilder had found some time ago. They also say that the previous software only work around will "sometimes" do the trick (but would not for me).
                                       
                                      Since so many people have run into this issue, I thought I'd update this thread to keep it current for anyone else yet to come along. Thanks to Microchip for making it official.
                                      -Adam
                                       
                                      #19
                                        mmullins_9999

                                        • Total Posts : 28
                                        • Reward points : 0
                                        • Joined: 4/28/2007
                                        • Location: The great state of Texas
                                        • Status: offline
                                        RE: I2C Master on PIC24FJ64 Series Wednesday, April 30, 2008 8:02 PM (permalink)
                                        0
                                        The errata that houta69 refers to is 80316f and it relates to the 0x3003 (A3) parts.  It is claimed that the I2C2 module works in this version without botbuilder's 'helper pin kludge', but it does not on mine.  I realized that I have an older revision (0x3002) for which I can't find a specific errata on Microchip's web site.  Maybe all I need to do is to switch to the newer part.  I'll give it a try.
                                         
                                        #20
                                          Online Bookmarks Sharing: Share/Bookmark
                                          Change Page: 1234 > | Showing page 1 of 4, messages 1 to 20 of 64

                                          Jump to:

                                          Current active users

                                          There are 0 members and 1 guests.

                                          Icon Legend and Permission

                                          • New Messages
                                          • No New Messages
                                          • Hot Topic w/ New Messages
                                          • Hot Topic w/o New Messages
                                          • Locked w/ New Messages
                                          • Locked w/o New Messages
                                          • Read Message
                                          • Post New Thread
                                          • Reply to message
                                          • Post New Poll
                                          • Submit Vote
                                          • Post reward post
                                          • Delete my own posts
                                          • Delete my own threads
                                          • Rate post

                                          2000-2013 ASPPlayground.NET Forum Version 3.9