#1810 PIC16: i2c_start and i2c_stop incomplete

open
nobody
PIC16
5
2013-07-16
2011-07-16
No

I think the routines i2c_start and i2c_stop in the pic16 port of the libio library are incomplete, application note AN989 suggests that i2c_start and i2c_stop should clear PIR1bits.SSPIF before setting SSPCON2bits.SEN or SSPCON2bits.PEN and not exit/return until it (PIR1bits.SSPIF) is set by the hardware.

Discussion

  • Fred Marquis

    Fred Marquis - 2011-07-16

    Note and test code

     
  • Diego Herranz

    Diego Herranz - 2011-07-19

    Another application note, AN735 (Using the PICmicro® MSSP Module for Master I2C) says:

    "An important item to note at this point, is when implementing a Master I2C controller with the MSSP module, no events can be queued. One event must be finished and the module IDLE before the next event can be initiated. There are a few of ways to ensure that the module is IDLE before initiating the next event [...]"

    In short, it shows 3 ways:

    - Generic idle check subroutine (Example 7): it checks for everything to be idle. It should be called before starting any event.
    - Specific event idle check (Example 8 and following): it should be checked after starting an event.
    - Interrupts (Example 11): when an interrupt occurs (SSPIF) last event has ended.

    I think that the best approach for sdcc would be the second one. Start and stop routines could be something like this:

    void i2c_start(void)
    {
    SSPCON2bits.SEN = 1;
    while (SSPCON2bits.SEN);
    }

    void i2c_stop(void)
    {
    SSPCON2bits.PEN = 1;
    while (SSPCON2bits.PEN);
    }

    Perhaps clearing SSPIF before starting these events might be useful too, although ISR should clear it, shouldn't it?

     
  • Fred Marquis

    Fred Marquis - 2011-07-19

    Yes, diegoherranz I agree I have also used the

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

    construction and found it works well, similarly I have used:

    PIR1bits.SSPIF=0;
    SSPCON2bits.SEN = 1;
    while (SSPCON2bits.SEN);

    which also works.

    My problem is that the example I have been looking at, trying and modifying are fairly simple and many of the status bits, AFAIK all change at the same time so more than one test can be used -- maybe in more complex cases this will not be the case.

    I'll have a closer read of AN735 and a play but it will be some time before I can get back to this

     
  • strobla

    strobla - 2011-07-19

    Dear Fred, dear Diego,

    have a look at one of my i2c functions. I agree with your ideas ...

    Regards, Strobl Anton

    uchar get_lm75_value(uchar *cdata, uchar addr)
    {
    i2c_idle();
    i2c_start();
    while(SSP1CON2bits.SEN){}; // wait until start condition is ready
    i2c_writechar(addr + 1); // want to read data from lm75
    i2c_idle();

    if (SSP1CON2bits.ACKSTAT == 1) { // 0 if found; 1 if NOT received ACK
    i2c_stop();
    while(SSP1CON2bits.PEN){}; // wait until stop condition is completed
    return 0;
    }
    *cdata++ = i2c_readchar();
    i2c_ack();
    while(SSP1CON2bits.ACKEN){};
    *cdata++ = i2c_readchar();
    i2c_nack();
    while(SSP1CON2bits.ACKEN){};
    i2c_stop();
    while(SSP1CON2bits.PEN){}; // wait until stop condition is completed
    return 1;
    }

     
  • Maarten Brock

    Maarten Brock - 2011-09-16
    • summary: i2c_start and i2c_stop incomplete --> PIC16: i2c_start and i2c_stop incomplete
     
  • Diego Herranz

    Diego Herranz - 2011-09-23

    After some more work with I2C, I think that this is not a bug.

    If you call i2c_idle(), it checks for SEN, PEN, etc. to be cleared, so it should be called after every i2_start(), i2c_stop(), i2c_ack(), etc. (also with macros)

    I think that i2c library is intended to be like that so, if you use interrupts for i2c, you don't call i2c_idle() and you don't have to do polling (you'l use the interrupt instead).

    If so, I think this bug should be closed.

    Thanks

     
  • Philipp Klaus Krause

    • Category: --> PIC16
     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks