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

16f1829 i2c master slave issue

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



Joined: 27 Oct 2012
Posts: 8
Location: united kingdom

View user's profile Send private message

16f1829 i2c master slave issue
PostPosted: Sun Feb 02, 2014 2:39 pm     Reply with quote

hi guys
after a bit of help on a problem as it's now driving me nuts, (have also asked CCS the same question and awaiting some response) I am using a 16f1829 as an I2C slave (on I2C1) to a 18f46k22 on the same board (220R resistors in series on SCL and SDA with a 2k4 resistor on each as a pullup), the 16f1829 also acts as a i2c master to some other devices (on I2C2) , the problem I have is it locks up the master (18f46k22), (though the slave keeps running fine) now if I disable the master (on the 16f1829) it doesn't lock up the master (18f46k22) and it runs fine as a slave, (I also have another 16f1829 on the same network which also works fine once the lockup from the first slave is cleared) my i2c is setup as
Code:
   #use i2c(Master,I2C2, fast=60000 ,stream = LocalI2C,force_hw) //sensor i2c
   #use i2c(Slave,I2C1,fast,force_hw,address=0x56,STREAM=i2c_host)

my main program however runs in the timer 4 interrupt as it needs to happen on time (though it makes no difference if I put this in the main while loop still locks it up)

the main bulk of the code is
Code:
#INT_SSP

void ssp_interupt ()

   unsigned int8 incoming, state;

   state = i2c_isr_state(i2c_host);

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

      if(state == 1)                      //First received byte is address
         {address = incoming;
          i2c_watchdog =0;
         }
      if(state >= 2 && state != 0x80)   //Received byte is data
        {
              scratchData[address++] = incoming;
        }
   }
   if(state > 0x80)                      //Master is requesting data
      {
       i2c_write(i2c_host,scratchData[address++]);
      }
}
/****************************************************************************/
#int_TIMER4
void  TIMER4_isr(void)//
  { if (i2c_watchdog < 100)
       i2c_watchdog ++;
    else // if communications aren't seen for 600ms reset controller variables
       {i2c_watchdog = 0;
       scratchdata[4] = 0;
       scratchdata[5] = 0;
       scratchdata[6] = 0;
       scratchdata[7] = 0;
       scratchdata[8] = 0;
       scratchdata[9] = 0;
       } 
     sensor = read_tank_sensor(TANK_SENS_ID); // sensor
     valve_switcher();
     set_analog_output(MAKE16(scratchdata[4], scratchdata[5]),false,0);

     if ( bit_test (scratchdata[10],2))
         {
     
         if ( bit_test (scratchdata[10],3))
            output_high(Q_P1_DIR);
         else
            output_low(Q_P1_DIR);
           

         set_analog_output_byte( scratchdata[6], scratchdata[7],false,1);
         SensorRecirc = read_recirc_sensor(RECIRC_SENS_ID); or
           
         }
         
     //alive status LED and output (use for measuring sample rate)   
     if (sec_time < 200)
       sec_time ++;
    else
       {sec_time = 0;
     if(!input_state(Q_ALIVE))
        output_high(Q_ALIVE);
     else
        output_low(Q_ALIVE); 
       }
  }

/****************************************************************************/

void main()
{
delay_ms(1000);
setup_timer_2(T2_DIV_BY_4,99,1);      //50.0 us overflow, 50.0 us interrupt
setup_timer_4(T4_DIV_BY_16,149,2); //600us interupt @32mhz

    set_pwm1_duty((int16)0);
   setup_ccp1(CCP_PWM_H_H |  CCP_PULSE_STEERING_B );
   setup_ccp2(CCP_PWM|CCP_SHUTDOWN_AC_L|CCP_SHUTDOWN_BD_L);
   set_pwm2_duty((int16)0);
 setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard

   enable_interrupts(INT_SSP);
   enable_interrupts(INT_TIMER4);
   
    initAout_i2c();
   enable_interrupts(GLOBAL);
   set_analog_output(0,true,0);
   set_analog_output(0,true,1);
   set_analog_output(0,false,0);
   set_analog_output(0,false,1);
//setup/initialise Communications


   while(TRUE)
 {
 }

}


I'm using version 5.018 of the compiler (though have tried this with 5.016,5.017 as well (the master is before the slave due to the issue with <5.017 (found that one out myself!)

I have a setup as well using 18f26k22 with a 16f1825 as the slave (exactly the same code except for the pin id's) this runs but also had lockup issues when I first wrote it which I fixed by taking all the complexity out of the interrupt so it was more stream lined

I have made sure all my device librarys are fully using the stream name as well so it's not that

so the question is any ideas? is this an school boy issue with my programming (i am more than willing to hold my hands up on that)? or am I battling a deeper CCS issue possible to do with library and their tracking of the stream names,? should I really be ditching the interrupt altogether and inlineing the slave reading as part of my main loop (though wouldn't know where to start on that as I guess I would have to track the bit registers)?

any help from anyone would be great

Thanks in advance

Graham

...the wheel might still be spinning but the hamsters long dead!
Ttelmah



Joined: 11 Mar 2010
Posts: 19447

View user's profile Send private message

PostPosted: Sun Feb 02, 2014 3:07 pm     Reply with quote

State 0x80, is 'unique'. On this state you have to read, and then write. You only read. This is the whole point about 'not releasing the clock', since it must not be released, till the write is done.

Then (minor) a slave I2C setup, does not have a 'speed'.

Best Wishes
technomation



Joined: 27 Oct 2012
Posts: 8
Location: united kingdom

View user's profile Send private message

PostPosted: Sun Feb 02, 2014 3:29 pm     Reply with quote

hi Ttelmah
I'm going to sound an idiot but do just mean
Quote:
if(state > 0x80) //Master is requesting data
{
i2c_write(i2c_host,scratchData[address++]);
}

should be
Quote:
if(state >= 0x80) //Master is requesting data
{
i2c_write(i2c_host,scratchData[address++]);
}


if so your right that is what it's supposed to be (been trying everything and didn't change that back so well spotted) and that didn't work either
kind regards
graham
Ttelmah



Joined: 11 Mar 2010
Posts: 19447

View user's profile Send private message

PostPosted: Mon Feb 03, 2014 4:01 am     Reply with quote

OK.
Now that is how it 'should be', but you still have the problem.

Some comments:

There is an erratum for this chip, that in one particular state (I2C mixed with SPI), the settings on one channel affect the other). Shouldn't apply in your case (meant to only be when you use slew rate limiting on one port as an SSP port....), but suggests there are some oddities about the interconnections between the channels. As such, it'd be worth trying swapping the two channels.

Then the SSP2 channel SDO2 line can be relocated. As such worth explicitly setting the affected bit in AFPCON, to ensure this is configured as you want.

Now, does your master (both the 46K22, and the 1829), correctly do the I2C_read(0) on the last transfer when reading data from the bus?. This is required by I2C, and some PIC I2C interfaces, won't recover, if this is not done before the I2C_stop.

You don't actually show us the master I2C code for the 1829. It is definately problematical to put this in the timer4 interrupt. Remember that a slave _must_ respond to things like write requests quite quickly, and if the code is inside the timer4 interrupt handling I2C transactions, it'll be stuck there for a long time (especially at 60000bps - why so slow?.).

Best Wishes
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