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 problems with a PIC18F6622

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



Joined: 15 Jan 2004
Posts: 10

View user's profile Send private message

I2C Slave problems with a PIC18F6622
PostPosted: Tue Jan 22, 2008 11:37 am     Reply with quote

I am using the Ex_slave.c example on a Pic18F6622 with a Diolan USB to I2C interface adapter.
I am unable to read from the Pic, the Diolan times out and reports that the Slave has dropped the SDA and SCL lines.

I have tried using the second I2C on the pic with the same results.
I can program some DAC's which I have on the second I2c via the Diolan adapter so I am pretty sure that my hardware is ok.

I have tried the same code with a Pic16F88 and the Diolan adapter and it works without any problems.

Has anyone used the 18F6622 as an I2C slave?
(I am using PCWH V3.234)

Code:

#include <18F6622.h>
#device adc=10

#FUSES NOWDT   
#FUSES WDT128   
#FUSES INTRC_IO       
#FUSES NOPROTECT     
#FUSES IESO         
#FUSES BROWNOUT   
#FUSES BORV25             
#FUSES NOPUT         
#FUSES NOCPD         
#FUSES STVREN         
#FUSES NODEBUG 
#FUSES NOLVP         
#FUSES NOWRT   
#FUSES NOCPB     
#FUSES NOEBTRB   
#FUSES NOEBTR     
#FUSES NOWRTD       
#FUSES NOWRTC   
#FUSES NOWRTB   
#FUSES FCMEN     
#FUSES LPT1OSC     
#FUSES NOMCLR 
#FUSES NOXINST
#FUSES BBSIZ1K

#use delay(clock=8000000)
#use     i2c(Slave,sda=PIN_C4,scl=PIN_C3,address=0xa0,force_hw)

BYTE address;
BYTE buffer[0x10] = {1,2,3,4,5,6,7,8,9,0};

#INT_SSP
void ssp_interupt ()
{
   int8 incoming;
   int8 state;

   state = i2c_isr_state();
   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]);
   }
}

void main()
{
   setup_adc_ports(AN0_TO_AN1|VSS_VDD);
   setup_adc(ADC_CLOCK_INTERNAL);

   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8);
   setup_wdt(WDT_OFF);
   setup_timer_1(T1_DISABLED);
   set_timer1(64535);   
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_SSP);

   while(TRUE)
   {
     restart_wdt();
   }
}
SB



Joined: 15 Jan 2004
Posts: 10

View user's profile Send private message

PostPosted: Thu Jan 24, 2008 8:54 am     Reply with quote

Just in case anyone is interested but I managed to fix my problem.

The i2c_isr_state() routine checks bit 0 of the SSP1BUF to see if it is a read or a write.
For some reason in the chip you have to look at bit 2 of SSP1STAT to see if it is a read or write.

If anyone know why this is the case I would be interested to know.

So using someones code from this forum I modified it slightly to look at the SSP1STAT.2 instead of SSP1BUF.0

Code:

#byte SSP1STAT = 0xFC7
#bit DA_BIT = SSP1STAT.5
#bit RW_BIT = SSP1STAT.2

#inline
int8 my_i2c_isr_state(void)
{
   static int8 i2c_state = 0x03;   
   int8 retval;
   
   if(!DA_BIT)          // If address byte was received
   {
      i2c_state = 0;    // Then clear state.
      if(RW_BIT)        // If it is a Read address
      {
         bit_set(i2c_state, 7);  // Then set bit 7 of state.
      }
   }       
   retval = i2c_state;
   i2c_state++;       
   return(retval); 
}

#INT_SSP
void ssp_interupt ()
{
   int8 incoming;
   int8 state;
   state = my_i2c_isr_state();
   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]);
   }
}
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