CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

I2C Slave Tx doesn't work, both data and clock pulled low

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
nehallove



Joined: 16 Jan 2008
Posts: 61

View user's profile Send private message

I2C Slave Tx doesn't work, both data and clock pulled low
PostPosted: Fri Mar 08, 2013 3:52 pm     Reply with quote

I have master PIC18f25k20 and slave 16f1937.

compiler version 4.0139

slave code:
//This is main.h

//#include <16F1825.h>
#include <16LF1937.h>
#device *=16 ICD=TRUE
#device adc=16

//#FUSES LP
#FUSES HS
#FUSES NODEBUG
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT_SW //No Watch Dog Timer, enabled in Software
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

//#use delay(clock=20000000)
#use delay(internal=16mhz)


//this is main.c

//! Library Files
#include <main.h>

#use I2C(SLAVE,sda=PIN_C4,scl=PIN_C3,address=0xB0,SLOW,FORCE_HW)


unsigned int8 address=0, buffer[16];

#INT_SSP
void ssp_interrupt ()

{
unsigned int8 incoming, state;

state = i2c_isr_state();
if((state == 0)||(state == 0x80))
i2c_read();
if(state >= 0x80)
i2c_write(0xAA);
else if(state>0)
buffer[address++] = i2c_read();

//if((address == 17)||(buffer[address-1] =='\r'))
//address = 0;

/*
if(state <= 0x80) //Master is sending data
{
if(state == 0x80)
incoming =i2c_read(2); //Passing 2 as parameter, causes the function to read the SSPBUF without releasing the clock
else
incoming = i2c_read();

//if(state == 1) //First received byte is address
//address = incoming;
if(state >=2 && state !=0x80) //Received byte is data
buffer[address++] = incoming;
}

if(state >= 0x80) //Master is requesting data
{
i2c_write(buffer[++address]);
}
*/
}

void main ()
{

enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);

while (TRUE)
{
}
}


Master Code:

try to read from I2C slave

while(1){
i2c_start();
i2c_write(0xB1);
x = i2c_read();
x = i2c_read();
i2c_stop();
}

Result:
if i use only one read operation, it doesn't read right. If i put two read operation then it reads 0xAA. In both condition after one loop cycle, slave pulls both data and clock line low. And both side freezes on #I2C() line.

Does anybody have a clue what is going on? Master write operation works.

nehal
_________________
nehal
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Fri Mar 08, 2013 4:12 pm     Reply with quote

1) Learn to use the code buttons.
Your code is 99% unreadable.

2) Trim code. We aren't here to read through swathes of stuff that is remmed out. Test programs should be as short as possible.

3) When doing multiple read transactions, the master needs to not ACK the last byte.

4) Time. Do you really think you can send stop, then immediately start as fast as possible, without pausing at all?.

5) As currently written, address will overflow buffer if you write, and will destroy the contents of the RAM.

6) Have you bothered to check for errata?. The 25K20, on older revisions has a completely non working master mode, and on all revisions has problems handling the stop event, which can be triggered by poor pull-ups, or not allowing any delays..... It is actually very difficult to get reliable I2C with this chip.
nehallove



Joined: 16 Jan 2008
Posts: 61

View user's profile Send private message

PostPosted: Fri Mar 08, 2013 5:34 pm     Reply with quote

Code:
//Fuses

#include <16LF1937.h>
#device *=16 ICD=TRUE
#device adc=16

 
#FUSES HS
#FUSES NODEBUG
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT_SW                   //No Watch Dog Timer, enabled in Software
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O


#use delay(internal=16mhz)



Code:
#use I2C(SLAVE,sda=PIN_C4,scl=PIN_C3,address=0xB0,SLOW,FORCE_HW)


unsigned int8 address=0, buffer[16];

#INT_SSP
void ssp_interrupt ()

{
   unsigned int8 incoming, state;
   
   state = i2c_isr_state();
   if((state == 0)||(state == 0x80))
      i2c_read();
   if(state >= 0x80)
      i2c_write(0xAA);
   else if(state>0)
      buffer[address++] = i2c_read();
}


void main ()
{

   enable_interrupts(GLOBAL);
   enable_interrupts(INT_SSP);
   
   while (TRUE)
   {
   }
}



Code:
Master Code:

try to read from I2C slave

while(1){
  i2c_start();
  i2c_write(0xB1);
  x = i2c_read();
  x = i2c_read();
  i2c_stop();
}


1) Learn to use the code buttons.
Your code is 99% unreadable.

I would like to apologize for the code. Every time it by default put the code in proper way. So didn't check the preview before posting it. I also trimmed it.

2) Trim code. We aren't here to read through swathes of stuff that is remmed out. Test programs should be as short as possible.

Once again sorry.

3) When doing multiple read transactions, the master needs to not ACK the last byte.

Well if that is the case the case then why only reading one byte doesn't work either.

4) Time. Do you really think you can send stop, then immediately start as fast as possible, without pausing at all?.

I actually have the break point after every master read operation. So I am not doing reading without pausing anyways.

5) As currently written, address will overflow buffer if you write, and will destroy the contents of the RAM.

As I said I am only using the master read operation. I have already verified master write operation works. That buffer check portion of code is already commented.


6) Have you bothered to check for errata?. The 25K20, on older revisions has a completely non working master mode, and on all revisions has problems handling the stop event, which can be triggered by poor pull-ups, or not allowing any delays..... It is actually very difficult to get reliable I2C with this chip.[/code]


    Of course I have checked the errata. This is an old product processor. We have already have used this processor as master I2C and ARM as slave I2C without any problem. We also have low pull resistors. This is just a test code so after one operation master always stops at break point.
    Even it is only one read operation I don't see any additional clock on the bus. Data collection is wrong and slave pulls the clock and data line low. By resetting the master PIC18F25K20 or clearing RCEN bit doesn't keep the line high. It stays pull low.

    I thought it is slave who still stays in some unknown data transmitting state and pull the bus low. I might be wrong but don't know what is going on. I am stuck and brain froze.
    Code:

    _________________
    nehal
    PCM programmer



    Joined: 06 Sep 2003
    Posts: 21708

    View user's profile Send private message

    PostPosted: Fri Mar 08, 2013 7:18 pm     Reply with quote

    Quote:
    Well if that is the case the case then why only reading one byte doesn't work either.

    Reading one byte means that single i2c_read() is the "last" one, and it
    must do a NACK.

    Read this thread about the NACK on the last i2c_read(), including links
    to the Philips specification:
    http://www.ccsinfo.com/forum/viewtopic.php?t=42965&highlight=nack
    nehallove



    Joined: 16 Jan 2008
    Posts: 61

    View user's profile Send private message

    PostPosted: Fri Mar 08, 2013 8:17 pm     Reply with quote

    Thanks PCM Programmer.

    By putting i2c_read(0) on the last byte reading stopped the pulling of data and clock bus. But

    i2c_start()
    x[0] = i2c_read();
    x[1] = i2c_read();
    x[2] = i2c_read(0);
    i2c_stop()

    but with above setting first byte x[0] is always 0x62 no matter what i send.
    if i use below code the receive byte is also only 0x62

    i2c_start()
    x[2] = i2c_read(0);
    i2c_stop()

    Any reason, it seems weird to me.
    _________________
    nehal
    PCM programmer



    Joined: 06 Sep 2003
    Posts: 21708

    View user's profile Send private message

    PostPosted: Fri Mar 08, 2013 8:26 pm     Reply with quote

    You don't send the slave's read address in either of those i2c transactions.
    How can the slave respond ? It has not been addressed.
    nehallove



    Joined: 16 Jan 2008
    Posts: 61

    View user's profile Send private message

    PostPosted: Fri Mar 08, 2013 8:33 pm     Reply with quote

    oh sorry i accidentally cut the line while copying on my reply i do use the address.

    i2c_start()
    i2c_write(0xB1);
    x[0] = i2c_read();
    x[1] = i2c_read();
    x[2] = i2c_read(0);
    i2c_stop()

    and

    i2c_start()
    i2c_write(0xB1);
    x[2] = i2c_read(0);
    i2c_stop()
    _________________
    nehal
    PCM programmer



    Joined: 06 Sep 2003
    Posts: 21708

    View user's profile Send private message

    PostPosted: Sat Mar 09, 2013 3:18 pm     Reply with quote

    Instead of using your programs to test the i2c slave, do this:

    Use the CCS example program Ex_Slave.c for the slave PIC:
    c:\program files\picc\examples\ex_slave.c

    Use the code in this post for the Master PIC:
    http://www.ccsinfo.com/forum/viewtopic.php?t=32368&start=3
    Note that the master code uses software i2c. It doesn't have FORCE_HW
    in the #use i2c() statement. Software i2c master is more reliable than
    hardware on many PICs.

    What is the Vdd voltage on each PIC ? Is it 5v or 3.3v ? Or are the
    PICs running at different Vdd voltages ?

    What is the value of the pull-up resistors used on SDA and SCL ?

    What is the length of the i2c bus ? (in inches or cm)

    Do you have a ground connection between the two PICs ?
    (Are they on the same board ?)
    nehallove



    Joined: 16 Jan 2008
    Posts: 61

    View user's profile Send private message

    PostPosted: Mon Mar 11, 2013 3:11 pm     Reply with quote

    Hi I used the code in ex_slave.c and use that code modify the routine a little bit since it reads the memory. But still the same thing. First byte is wrong on reading. Even on oscilloscope it show 0x62.

    PICs running at different Vdd voltages ?
    Both pics are at same voltage.

    What is the value of the pull-up resistors used on SDA and SCL ?
    Pull up is 1.4 k

    What is the length of the i2c bus ? (in inches or cm)
    An inch

    Do you have a ground connection between the two PICs ?
    (Are they on the same board ?)

    They are different boards but they have common ground and supply voltage.
    _________________
    nehal
    nehallove



    Joined: 16 Jan 2008
    Posts: 61

    View user's profile Send private message

    PostPosted: Mon Mar 11, 2013 3:23 pm     Reply with quote

    I also removed the force hardware on master side.
    _________________
    nehal
    Ttelmah



    Joined: 11 Mar 2010
    Posts: 19513

    View user's profile Send private message

    PostPosted: Mon Mar 11, 2013 3:47 pm     Reply with quote

    I notice you have several conflicts in the fuses on the slave device:
    The watchdog is specified to be both software enabled, and disabled. Only one can be used at a time. You also have the oscillator set to use a crystal, but the delay setup to use the internal RC. Things like this can lead to unexpected problems. Also, a slave device does not have a speed. Only master devices should specify this.

    Best Wishes
    nehallove



    Joined: 16 Jan 2008
    Posts: 61

    View user's profile Send private message

    PostPosted: Mon Mar 11, 2013 5:04 pm     Reply with quote

    I changed the fuses as below but still the same.

    Code:
    #include <16LF1937.h>
    #device *=16 ICD=TRUE
    #device adc=16


    #FUSES INTRC_IO
    #FUSES NODEBUG
    #FUSES NOWDT                    //No Watch Dog Timer
    #FUSES NOBROWNOUT               //No brownout reset
    #FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O


    #use delay(internal=16mhz)

    _________________
    nehal
    Display posts from previous:   
    Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
    Page 1 of 1

     
    Jump to:  
    You cannot post new topics in this forum
    You cannot reply to topics in this forum
    You cannot edit your posts in this forum
    You cannot delete your posts in this forum
    You cannot vote in polls in this forum


    Powered by phpBB © 2001, 2005 phpBB Group