• AVR Freaks

Hot!I2C library incomplete

Author
sn4tch3r
Starting Member
  • Total Posts : 32
  • Reward points : 0
  • Joined: 2011/07/06 04:08:27
  • Location: India
  • Status: offline
2015/01/02 02:12:25 (permalink)
0

I2C library incomplete

Hi,
Currently working with the MCP23017(I2C) with PIC18f46k22 (MSSP2) i.e. PIND0 and PIND1.
Normally i would prefer using my custom functions and header files but thought to try the inbuilt peripheral libraries by microchip.
 
In function openI2C(sync,slew) 
In my opinion there should have been a provision for SSPxADD as well. I also assumed that the analog feature would be disbaled wen i used the i2c.h but had to do that manually as well.
So my code for init_i2c read as follows:

SSP2ADD = 0x27; //should be 0x27 for 100kHz , SSPADD = [(FOSC/BitRate)/4]-1
ANSELDbits.ANSELD0 = 0;
ANSELDbits.ANSELD1 = 0;
OpenI2C2(MASTER,SLEW_OFF);
StartI2C2();

 
I read the document MPLAB_XC8_Peripheral_Libraries.pdf available in the microchip directory. On page 818 all the list of i2c commands for PIC18f46k22 are mentioned but no sign of SSP2ADD or ANSELD bits are mentioned.
I wanted to know abt what my approach of using the inbuilt library was right or is there any alternate way of passing arguments to inbuilt i2c.h library. If yes please guide me in doing so.
 
#1

7 Replies Related Threads

    ric
    Super Member
    • Total Posts : 24280
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: I2C library incomplete 2015/01/02 02:29:59 (permalink)
    +9 (5)
    I'd drop the supplied library in the bin, and just do it yourself.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #2
    Ian.M
    Super Member
    • Total Posts : 13267
    • Reward points : 0
    • Joined: 2009/07/23 07:02:40
    • Location: UK
    • Status: offline
    Re: I2C library incomplete 2015/01/02 03:26:18 (permalink)
    +7 (4)
    +1
    Its a half-a**ed port of the C18 PLIB provided for 'compatibility' reasons and is buggier than the average antfarm.

    --
    NEW USERS: Posting images, links and code - workaround for restrictions.
    I also support http://picforum.ric323.com because this forum is sometimes too broken to use!
    #3
    sjb741
    Super Member
    • Total Posts : 805
    • Reward points : 0
    • Joined: 2010/01/25 08:45:39
    • Location: 0
    • Status: offline
    Re: I2C library incomplete 2015/01/13 03:06:41 (permalink)
    +2 (1)
    I think Microchip need to "draw a line" under what seems to be a voluminous code base which has not got their serious support for new work, fixes etc - put it under a new page "legacy, unsupported code base" and try to forget it otherwise. Of course, all possible help should be offered for existing users to migrate to the new code base.
     
    It seems the user is tempted down the libray path, only to be often utterly defeated by out of date documentation, unsupported chips, and easily fixed indentifier issues (SSP1CON1 vs SSPCON for instance).
     
    Example ticket:
    Q: What are the plans, if any, for some kind of mid-range peripheral library ?
       A: ...The MPLAB Code Configurator (MC2) is a user friendly plug-in tool for MPLAB X IDE which generates drivers for controlling and driving peripherals of PIC micro-controllers, based on the settings and selections made in the Graphical User Interface (GUI)...

    Q: "The device used in the selected Main Project is not currently supported by MCC
       A: We are looking into it...
       A: ...MCC doesn't have support for PIC16F886 device.
       A: ...It is mainly for new design with our new PIC16F1xxx family of devices. As of now, there is no plan on supporting older devices PIC10/12/16xxx...



    One thing that hinders code portability though is that where a device has only one module of a given type (eg PIC16F886 has one MSSP), it does not have an alias that is compatible with a device having more than one module of a given type.

    So, there are ("SSPCON", "SSPCON2") for which it would be nice to have pre-defined (in pic16f886.h etc)

    #define SSP1CON1 SSPCON
    #define SSP1CON2 SSPCON2
    post edited by sjb741 - 2015/01/13 03:08:04
    #4
    PStechPaul
    Super Member
    • Total Posts : 2433
    • Reward points : 0
    • Joined: 2006/06/27 16:11:32
    • Location: Cockeysville, MD, USA
    • Status: online
    Re: I2C library incomplete 2015/02/02 19:20:40 (permalink)
    0
    I just finished debugging and getting to work a custom I2C library as well as an LCD library that uses an I2C to LCD module for 16x2 and similar LCD modules. I will attach the code "as is" and you may need to make changes to registers and values to work for your specific application. This process took several days off and on, going through various pages of code for the PIC as well as the Arduino, and in assembly as well as C. The I2C functions and macros are basically extracted from the i2c.h file and the plib library files supplied by Microchip. I found some definite bugs and "gotchas" and I had to add a "hack" to fix a blocking function that gets caught in an endless loop if the MSSP module is disabled (I don't know why - it should be enabled).
     
    This is the hack:
     
    void I2C_start(void)
    {
        if(SSP1CON1bits.SSPEN == 0)
           SSP1CON1 = 0x28;
        SSP1CON2bits.SEN = 1; // Send start bit
        while(SSP1CON2bits.SEN);
    }

     
    The attached zipfile is for my TigTac project which will be a Transistor Ignition and Tachometer using a PIC16F1825.
     
    It may be useful to make separate libraries for each device, or at least for devices which share the same version MSSP. The supplied libraries attempt to do that with conditionals and definitions based on the pconfig file, but there are errors. For example, see the following from i2c.h:
     
    #if defined (I2C_V2) || defined (I2C_V3) || defined (I2C_V5) || defined (I2C_V6) || defined (I2C_V6_1)
    #define IdleI2C1() while ((SSP1CON2 & 0x1F) | (SSP1STATbits.R_W))
    #endif

    #if defined (I2C_V6_2)
    #define IdleI2C1() while ((SSP1CON2 & 0x1F) | (SSP1STATbits.R_NOT_W))
    #endif

    #define IdleI2C IdleI2C1

     
    The R_NOT_W bit should actually be SSP1STATbits.R_nW, at least for the PIC16F1825.
     
    [edit] I don't know what happened to the attached file??
     
    Here is a link to it on my server: http://enginuitysystems.com/files/TigTac.zip
    post edited by PStechPaul - 2015/02/02 19:33:02

     
    #5
    Mysil
    Super Member
    • Total Posts : 3421
    • Reward points : 0
    • Joined: 2012/07/01 04:19:50
    • Location: Norway
    • Status: offline
    Re: I2C library incomplete 2015/02/03 00:30:50 (permalink)
    +1 (1)
    Hi,
    There are more small snags around Plib libraries for different devices.
    For some devices, OpenI2C(...) take care of (re)setting Tristate register bits to input,
    while for other devices, no such action is attempted.
    Then for some operations, there are both macro definition and functions with the same name, 
    but with different functionality:
    E.g  for StartI2C1()   the macro will wait in a busy loop until signalling is complete,
    #define StartI2C1()  SSP1CON2bits.SEN=1;while(SSP1CON2bits.SEN) 

    but the function with the same name, just set the control bit and return to caller.
    void StartI2C1( void )
    {
        SSP1CON2bits.SEN = 1;            // initiate bus start condition
    }

    Both blocking and non-blocking functions may be useful depending on circumstances,
    but identical function names with different behaviour?
    Neither of these perform error checking of any kind.
    As far as I know, I2C specification suggest that master device should check that bus is free and not jammed before initiating Start condition signalling.
    I2C hardware do this checking, both before signalling is started, and during the procedure,
    and what happen when hardware decide there is a problem?
    I2C give up the signalling attempt, set some status bits and do nothing more:
    The SEN bit that was set by software is cleared (there is No start condition signalling going on any more),
    S bit or P bit may be set or clear depending on the reason for the failure.
    BCL bit is probably set (Bus Collision), but that bit is Not in the SSPxSTAT register,
    it is in a interrupt register, PIR2bits.BCL1IF or PIR3bits.BCL2IF.
    IdleI2Cx(); function do Not check this, and do not return a function value,
    so cannot report a problem even if it was detected.
    This is a possible cause for the problem and workaround reported earlier in this thread.
     
    In fact, IdleI2Cx() function do not check if the I2C Bus is i a Idle state as defined by I2C specification, 
    what it do, is to wait for previous operation started by the same MSSP module to be completed.
     
    Also Note, that Write Collision (SSPxCON2bits.WCOL) is different from Bus Collision (PIRybits.BCLxIF).
    Write Collision is caused by code stumbling in its own logic, while Bus Collision is caused by events on the I2C bus.
     
    In Device support file for PIC18F26K22, for I2C Status register SSP2STAT,  there are several alternative names declared for some bits:
    SSP2STATbits.R_NOT_W,  SSP2STATbits.R_nW,  SSP2STATbits.R,  SSP2STATbits.W,
    SSP2STATbits.nW,  SSP2STATbits.R_W,  SSP2STATbits.NOT_WRITE,  SSP2STATbits.nWRITE,
      SSP2STATbits.I2C_READ2,  SSP2STATbits.READ_WRITE2,  SSP2STATbits.RW2,  SSP2STATbits.R_W2,  SSP2STATbits.R_nW2,  SSP2STATbits.nW2,  SSP2STATbits.nWRITE2.
    All these for the same bit
     
    For SSP1STAT there is also a selection, but not quite the same, there is a SSP1STATbits.NOT_W that is not available for SSP2STAT.
     
    In addition to these typedefs, there is a similar selection of bitfield macro definitions, and a heap of single bit macro definitions. There are also definitions for SSPSTAT as alias to SSP1STAT.
    Doing a file compare between Device support file for PIC18F26K22 and PIC18F46K22 show no differences between definitions for any MSSP registers.
    Most Plib I2C examples I have seen, show wery simple blocking code.
    That is not very suitable for I2C communication.
     
    A few days ago, I tried MPLAB Code Configurator (MCC)  for PIC18F26K22,
    and it came up with a Interrupt-based non-blocking I2C driver that work with the sensor I tried.
    I have not tested it much, but on first impression, it looks reasonable.
     
    Regards,
       Mysil
    post edited by Mysil - 2015/02/03 08:33:26
    #6
    sjb741
    Super Member
    • Total Posts : 805
    • Reward points : 0
    • Joined: 2010/01/25 08:45:39
    • Location: 0
    • Status: offline
    Re: I2C library incomplete 2015/02/03 02:41:25 (permalink)
    0
    Whilst working on my epic poem, "Ode to the portability of Microchip's code-base", I was glad of the Microchip Thesaurus                               

    SSP1STATbits.R_nW
    Synonyms
       SSP1STATbits.R_NOT_W, SSP1STATbits.R_W....
     
    Smile
     
    #7
    girish_kotr
    New Member
    • Total Posts : 1
    • Reward points : 0
    • Joined: 2019/02/02 09:16:05
    • Location: 0
    • Status: offline
    Re: I2C library incomplete 2019/10/22 02:55:05 (permalink)
    0
    Hi,
    I'm facing some issue in I2C protocol by using PIC18F46K22. When I'm trying to set the acknowledgement (SSP1CON2bits.ACKEN = 1;), it is going in hang mode. Nothing will work, please find the my code below:
     
    void I2C_Initialize(const unsigned long feq_K) //Begin IIC as master feq_K=100
    {
      TRISC3 = 1;  //Set SCL pint as input pin
      TRISC4 = 1;  //Set SDA pin as input pin

      ANSELCbits.ANSC3=0;       //Disable Analog pin
      ANSELCbits.ANSC4=0;       //Disable Analog pin
     
     
      SSP1CON1=0b00101000;;    /* 0x00101000 - Enable SSP port for I2C Master mode, clock = FOSC / (4 * (SSPADD+1))*/
      SSP1CON2=0b00000000;
      SSP1CON3=0b00000000;
     
      SSP1STAT=0b00000000;
      SSP1ADD=(_XTAL_FREQ/(4*feq_K*1000))-1;      //_XTAL_FREQ=20MHz and feq_K=100
    }

    void I2C_Hold()
    {
        while (   (SSP1CON2 & 0b00011111)    ||    (SSP1STAT & 0b00000100)   ) ; //check the bis on registers to make sure the IIC is not in progress
    }
     
    unsigned short I2C_Read(unsigned short ack)
    {
      unsigned short incoming;
      I2C_Hold();
      SSP1CON2bits.RCEN = 1;
     
      I2C_Hold();
      incoming = SSP1BUF;      //get the data saved in SSP1BUF
     
      I2C_Hold();
      SSP1CON2bits.ACKDT = (ack)?0:1;    //check if ack bit received 
      SSP1CON2bits.ACKEN = 1;            //--> It will get stuck here
     
      return incoming;
    }
     
    In my program I'm not using interrupts. I tested same code for PIC16F877A and it is working fine.
    #8
    Jump to:
    © 2019 APG vNext Commercial Version 4.5