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 and PIC18F6722

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







I2C and PIC18F6722
PostPosted: Thu Mar 20, 2008 8:19 pm     Reply with quote

Hello,

I am having an odd issue with using the I2C bus to communicate between 2 PIC18F6722 chips. It works in FAST mode but not SLOW mode. The oscilloscope shows all normal until reading back to the slave (see comment in code). I would leave in FAST mode but the I2C locks up about once per day.

Slave code is from EX_SLAVE.C example.

The master settings are
Does not work with
Code:
#use i2c(Master,sda=PIN_C4,scl=PIN_C3,force_hw)


But does work with
Code:
#use i2c(Master,fast, sda=PIN_C4,scl=PIN_C3,force_hw)



Code to read 2 bytes from the slave is:
Code:
   i2c_start();
   i2c_write(0xA0);  // slave address write
   i2c_write(4);       // data area to read from
   i2c_start();
   i2c_write(0xA1);  // slave address read
   StatByte= i2c_read();   // SDA line is stuck low here
   BillState = i2c_read(0);
   i2c_stop();


Compiler version is 3.249

Thanks for your help.

John
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Mar 20, 2008 8:33 pm     Reply with quote

Post the slave program. Show the #include, #fuses, #use delay(),
and #use statements. The program should be compilable without errors.
jmorrow333
Guest







PostPosted: Thu Mar 20, 2008 8:50 pm     Reply with quote

Here is the slave interrupt code and fuses. I didn't post the full code it is 3k lines long.


Thanks!


Code:


#include <18F6722.h>

//#define USE_ICD

#ifdef USE_ICD
   #device ICD=TRUE
   #FUSES NOWDT
   #FUSES DEBUG                     //Debug mode for ICD
#else
   #FUSES WDT
   #FUSES NODEBUG                  //No Debug mode for ICD
#endif

#device adc=8
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES HS                       //High speed Osc (> 4mhz)
#FUSES NOPROTECT                //Code not protected from reading
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES NOBROWNOUT               //No brownout reset
#FUSES BORV25                   //Brownout reset at 2.5V
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOCPD                    //No EE protection
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES LVP                      //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOCPB                    //No Boot Block code protection
#FUSES NOEBTRB                  //Boot block not protected from table reads
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES LPT1OSC                  //Timer1 configured for low-power operation
#FUSES MCLR                     //Master Clear pin enabled
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES BBSIZ1K                  //1K words Boot Block size

#use delay(clock=20000000,RESTART_WDT)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=COM1)
#use rs232(baud=9600,parity=N,xmit=PIN_G1,rcv=PIN_G2,bits=8,stream=COM2)
#use i2c(Master,sda=PIN_C4,scl=PIN_C3,force_hw)


//Interrupts are set up as
   enable_interrupts(INT_RDA);
   enable_interrupts(INT_SSP);
   enable_interrupts(GLOBAL);

// I2C interrupt routine
#int_SSP
SSP_isr()
{
   char incoming, state, offset,Temp;


/*
I2C comm with processor 2

Commands
Poll        1     Any Data?
Stack Bill  2     Stack the bill
Return Bill 3     Return the Bill
Get Data    4     Get the data

Replys
ACK            0x10  No data
Bill inserted  0x11  Bill has been inserted into bill accepter
Mag read       0x12  Mag read has occured
Barcode read   0x12  Barcode read has occured
Data           0x13  Return data in response to get data command

*/


   state = i2c_isr_state();
   if(state < 0x80){                     //Master is sending data
      incoming = i2c_read();
      if(state == 0){                     //First received byte determines which buffer data goes into
         TargetBuffer = incoming;
      }
      if(state == 1){                     //Second received byte is offset for that buffer
         Offset = incoming;
      }
      if(state >= 2){                   // all rest of bytes go into the buffer
         switch(TargetBuffer){
            case 1:
               if((offset+state-2)<150){
                  InBufferMagReader[offset+state-2] = incoming;
               }
               else{
                  MagSerPortEn = FALSE;      // Shut down the port
                  I2COutBuffer[0] = (I2COutBuffer[0]&0x01)|(PortStates<<1);   // Send new port states
                  SendPortStatesFlag = TRUE;   // Notify SS of new settings
               }
               break;
            case 2:
               if((offset+state-2)<100){
                  InBufferBarcodeReader[offset+state-2] = incoming;
               }
               else{
                  BarcodeSerPortEn = FALSE;      // Shut down the port
                  I2COutBuffer[0] = (I2COutBuffer[0]&0x01)|(PortStates<<1);   // Send new port states
                  SendPortStatesFlag = TRUE;   // Notify SS of new settings
               }
               break;
            case 3:
               InBufferBillAccepter[offset+state-2] = incoming;
               break;
            // no case 4 -- no write to buffer, use for reading from slave      


         }   // end switch
      } // end state >=2
   }   // end state < 0x80
   if(state >= 0x80){                     //Master is requesting data

      i2c_write(I2COutBuffer[state-0x80]);   // GBO 2/6/08
      if((state-0x80) == 1)               // GBO 2/6/08
         I2COutBuffer[1] = 0;            // GBO 2/6/08
   }


}



John
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Mar 20, 2008 9:52 pm     Reply with quote

Quote:
Here is the slave interrupt code and fuses.

#FUSES LVP

#use i2c(Master,sda=PIN_C4,scl=PIN_C3,force_hw)


1. You should only use LVP if you're using a Low Voltage Programmer.
Very few people ( < 1%) use an LVP programmer. If you have
an ICD2, ICD-U40, etc., then change the fuse to NOLVP.
Do that in all your programs.

2. Your #use i2c() statement is for master mode. For slave mode, you
need to change it to 'Slave' and also specify the slave address.

3. Also, I would add ERRORS to both of your #use rs232() statements.

4. Probably, you should add a #priority statement and give the SSP
interrupt priority over the RDA interrupt.
Guest








PostPosted: Fri Mar 21, 2008 5:55 am     Reply with quote

Oops, I posted the fuses for the master.

Good catch on the RS232 errors, I usually do.

Errata #7 for the 8722 family recommends not using high priority interrupts due to an error in the fast return (RETFIE)

Thanks.

Fuses for Slave
Code:
#include <18F6722.h>

//#define USING_ICD

#ifdef USING_ICD
   #device ICD=TRUE
   #FUSES DEBUG                    //Debug mode for use with ICD
   #FUSES NOWDT
#else
   #FUSES NODEBUG
   #FUSES WDT
#endif

#device adc=8
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES HS                       //High speed Osc (> 4mhz)
#FUSES NOPROTECT                //Code not protected from reading
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES NOBROWNOUT               //No brownout reset
#FUSES BORV25                   //Brownout reset at 2.5V
#FUSES PUT                      //Power Up Timer
#FUSES NOCPD                    //No EE protection
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOCPB                    //No Boot Block code protection
#FUSES NOEBTRB                  //Boot block not protected from table reads
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES LPT1OSC                  //Timer1 configured for low-power operation
#FUSES MCLR                     //Master Clear pin enabled
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES BBSIZ1K                  //1K words Boot Block size

#use delay(clock=20000000, restart_wdt)
#use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=COM1,enable=PIN_F5,errors)
#use rs232(baud=9600,parity=N,xmit=PIN_G1,rcv=PIN_G2,bits=8,stream=COM2,errors)
#use i2c(Slave,slow,sda=PIN_C4,scl=PIN_C3,force_hw,address=0xa0)



John
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