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 support@ccsinfo.com

I2C weirdness

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



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

I2C weirdness
PostPosted: Fri Aug 08, 2008 11:02 am     Reply with quote

I'm using the latest compiler (4.077?) and a PIC 18F452.
I'm talking to the pic using I2C. I'm sending it data about every 30-40ms. There are 7 identical setups on the bus(except for address). After a few minutes the one or 2 of the boards will randomly stop responding. Timer 2 is still firing, and the Serial interrupt still works. I put in some code so that after it quits responding I send a serial packet to the board and it responds with the data in the I2C buffer. It seems that whenever it gets in this condition then all the data in the buffer is the same, it is the address of the PIC.


Code:
#INT_SSP
void ssp_interupt()
{
    int i;
    BYTE incoming, state;
//    int pinnumber,pinstate;
   state = i2c_isr_state();
    currentstate=1;
   if(state < 0x80)                     //Master is sending data
   {
       incoming = i2c_read();
        buffer[bytecounter]=incoming;
        bytecounter++;
       if(bytecounter ==7 )              //First received byte is address
        {
            bytecounter=0;
                if(buffer[1]==16)                 //PWM
                    {
                        bigcounter++;
//                        printf("pwm %ld\r\n",bigcounter);
                    ramp=buffer[2];
                    ID1 =buffer[3];
                    pwm1=buffer[4];
                    ID2 =buffer[5];
                    pwm2=buffer[6];
//                    sprintf(SERIAL_BUFFER,"pwm r:%d %d:%d %d:%d\0",ramp,ID1,pwm1,ID2,PWM2);                     
                    sprintf(SERIAL_BUFFER,"pwm %d:%d %d:%d\0",ID1,pwm1,ID2,PWM2);                     
                    pwm();
                    if(debug==1)
                        printf("%s",SERIAL_BUFFER);                     
                       
                    }

                else {}
        }
        if(bytecounter>7)// too many bytes, something is wrong
        {
            bytecounter=0;
            return;   
        }
                   

   }
   if(state == 0x80)   //Master is requesting data
   {
          for(i=0;i<15;i++)
            {
                delay_ms(1);
//              i2c_write(values[i]);
            }

      actionflag=1; //0 = nothing, 1 = read, 2 = change address
      bytecounter=0;
   }
   currentstate=2;
}


So when I get a serial packet I'm doing this
Code:
       printf("bytecounter = %d \r\n",bytecounter);
        for(i=0;i<7;i++)
            printf("buffer%d = %d \r\n",i,buffer[i]);


and it comes back with something like
buffer0 = 68
buffer1 = 68
buffer2 = 68
buffer3 = 68
buffer4 = 68
buffer5 = 68.... and 68 is the address to the board.

So to me it looks like
incoming = i2c_read(); is always returning the same thing (after it gets in this weird mode)

Any idea what would cause this?
Or any way to get out of it if I detect I'm in it?
It works for anywhere from 30 seconds to 30 minutes then a board will randomly get this way. resetting the board brings it back to operational.
Any help will be greatly appreciated.
_________________
Ringo Davis
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Aug 08, 2008 11:23 am     Reply with quote

I don't really know, but just scanning your code, it has massive delays
throughout the isr. It has sprintf, printf, delay_ms() in a loop, and it calls
a pwm() routine.

I would start by commenting all of these massive delays, and then see
if you still get the lockup. Get rid of that loop. Change it so it just
transmits one byte. In other words, strip down the program to the
minimum and test it.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri Aug 08, 2008 11:29 am     Reply with quote

From the release notes:
Quote:
4.077 Some problems with slave I2C have been fixed, see the newest EX_SLAVE.C

I haven't checked the changes CCS made to i2c_isr_state function but looking at the new ex_slave.c example it requires a (minimal) change to your ISR function.

Code:
   if(state < 0x80)                     //Master is sending data
to:
Code:
   if(state <= 0x80)                     //Master is sending data
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Fri Aug 08, 2008 11:34 am     Reply with quote

Thanks, I'll make minor change using the <= and I'll start stripping out stuff and see if minimal code works ok.
Ringo
_________________
Ringo Davis
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Sat Aug 09, 2008 1:09 pm     Reply with quote

The new ex_slave shows
Code:
The latest version of ex_slave.c has something I don't understand.

   if(state <= 0x80)                     //Master is sending data
   {
      incoming = i2c_read();
      if(state == 1)                     //First received byte is address
         address = incoming;
      if(state == 2)                     //Second received byte is data
         buffer[address] = incoming;
   }
   if(state == 0x80)                     //Master is requesting data
   {
      i2c_write(buffer[address]);
   }


How can it be master sending if it is <=80 and
master requesting if it is =80

80 would trigger both, is this correct?

I took out all the delay stuff now It has been running for about an hour with no issues, so I'm hoping it is fixed.
It would be nice however to have code in place so that if it happens again it can correct itself. Is there a way to reset the I2C port without resetting the entire pic?

Thanks
Ringo
_________________
Ringo Davis
Ttelmah
Guest







PostPosted: Sat Aug 09, 2008 3:12 pm     Reply with quote

If I2C_ISR_STATE, returns '0x80', then the slave has _received_ the address byte, from the master saying 'I want to read'.
Basically, for the master writing, the first time through, the state will be '0', corresponding to the I2C address byte saying 'I want to write' this results in a read, and nothing else. Then the next time, the state will be '1', which results in the read byte being stored as the internal address to talk to. Then a '2', results in the data being transferred to this address.
For the reading, state 0, says 'I want to read', but still needs to the address byte to be read from the input register. Then after this is read, the new byte wanted has to be read from the local memory, and written to the register, ready for the master to read it.
As shown, the code example is only capable of handling a single byte, not allowing automatic incrementing for states 81, 82 etc..
Code:

I2C_ISR_STATE      Byte to be read     Byte to be written

0                           Yes                      No
1                           Yes - I2C Address No
2                           Yes - data             No
3                           Yes - data             No
.....

0x80                      Yes - I2C Address  Yes
0x81                      No                        Yes
.......

The code takes advantage of the first part to automatically perform the reads for state 0, and 80, but just ignores the data read.

Best Wishes
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Mon Aug 11, 2008 1:06 pm     Reply with quote

I found this post on resetting the I2C port. I'm gonna put this code in place just in case.
http://www.ccsinfo.com/forum/viewtopic.php?t=34634
Thanks
Ringo
_________________
Ringo Davis
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