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

General Call Problem with I2C Slave code within PIC16F1936

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



Joined: 30 Mar 2011
Posts: 6
Location: Hampshire

View user's profile Send private message

General Call Problem with I2C Slave code within PIC16F1936
PostPosted: Wed Mar 30, 2011 7:51 am     Reply with quote

I have a problem with General Call in my I2C slave code. I hope that someone can help.
I have copied the format of the pksa.c file in the Microchip website. The main difference is that my code is within an ISR. I have four states which are derived from masking SSPSTAT for relevant bits.
Everything seems to work fine until I address my slave with General Call.
Then things go a bit strange. Sad

If the previous command to my slave was purely writing data from the Master, then the General Call works absolutely fine.
However, if the previous command to my slave includes the Master reading data from the slave (which also works fine), the General Call goes 'screwy' after this point.
My slave always generates an ACK (addr match), but the R/W bit is set! This bit stays set for every subsequent data byte written from Master to Slave. As my states are expecting the R/W bit to be clear when writing data in to slave, the data is being lost!

This happens 100% of the time. The only way I can use General Call to write commands in to the slave, is to precede the General Call with a 'Unique I2C Address match' command containing purely write bit set data.
After which General Call works again.

I currently only use General call to change the unique I2C Address of the Slave.

CCS Compiler Version 4.119. PIC16F1936.
Code:

#define _STATUS_MASK      0x2C
SSPSTAT = 0x80;         //Slew rate disabled for standard speed mode (100KHz)

SSPCON1 = 0x36;            
GCEN = ENABLED;               
SSPCON2 = 0x81;            
SSPCON3 = 0x00;   

Cut down code


#INT_SSP
void i2c_isr(void)
{

   BYTE incoming, _I2C_State;
   static byte index = 0x00;
   byte temp1;
   state = i2c_isr_state();   

     _I2C_State = SSPSTAT & _STATUS_MASK;

   switch (_I2C_State)
   {

   case ADDR_WRITE:          

   AddressedToMe = TRUE;   
   incoming = SSPBUF;               index = 0x00;
   break;


   case DATA_WRITE:   
      
   incoming = SSPBUF;
   index++;
   if (index < MAXBUFFERSIZE)            {
   CommsReceiveBuffer[index-0x01] = incoming;      }
   else
   {
   CommsReceiveBuffer[MAXBUFFERSIZE-0x01] = incoming;   }

   break;

   case ADDR_READ:             
                index = 0x00;      
   case DATA_READ:
   {

   NeedToWriteToMaster = TRUE;         SSPBUF = CommsSendBuffer[state - 0x80];      

   if ((CommsReceiveBuffer[COMMANDPOSITION] == READ_FROM_NV_MEMORY_REQ) && (DataReadFromEeprom == FALSE))
   {
   I2C_CLK_LINE_STATE = HOLD;            ReadFromEeprom();
   DataReadFromEeprom = TRUE;
   }

   if (index <= MAXBUFFERSIZE)            {

   do
   {
   WCOL = 0;
   SSPBUF = CommsSendBuffer[index];
   }while(WCOL);
   I2C_CLK_LINE_STATE = RELEASE;
                     index++;
                }
   else
   {
   do
   {
   WCOL = 0;
   SSPBUF = 0xFF;
   }while(WCOL);
   I2C_CLK_LINE_STATE = RELEASE;
                     index++;
                }
}



}

SSPIF = CLEAR;   
enable_interrupts(INT_SSP);
I2C_CLK_LINE_STATE = RELEASE;
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19346

View user's profile Send private message

PostPosted: Wed Mar 30, 2011 8:12 am     Reply with quote

I don't think a GCA, with 1 in the low bit is legal.
GCA, is a broadcast from the master to all slaves on the bus. The I2C documentation only shows this with a 0 in the low bit. How can you broadcast to everyone, then have a reply?. After all every device on the bus would reply to this?.
You can set an address inside GCA, and then address a specific slave, and have this reply, but a 'general call', with all devices replying, would break the bus....

Best Wishes
Steve Smith



Joined: 30 Mar 2011
Posts: 6
Location: Hampshire

View user's profile Send private message

Reply to Ttelmah
PostPosted: Wed Mar 30, 2011 8:28 am     Reply with quote

Firstly, thank you for looking at my issue and replying so quickly.
I agree, a GCA with a 1 in the R/W bit is illegal. Also, if I tried to do this, all slaves would talk at once. However, this is what the PIC is generating within SSPSTAT register. I can not control it. This is the problem I have.

When I carry out a General Call, all I wish to do is to write a command and data to the slave, and because of this I would expect the R/W bit to be 0 (write). I do not ever try to read data from the slave under General Call.
The R/W bit seems to be set to a 1 by the PIC during a General Call, ONLY if the previous communications between Master and Slave included the Master reading data from the Slave. If the previous communcation was the Master purely writing to the Slave, then the next General Call works absolutely fine.

Regards
Steve Smith



Joined: 30 Mar 2011
Posts: 6
Location: Hampshire

View user's profile Send private message

PostPosted: Wed Mar 30, 2011 8:41 am     Reply with quote

Just to clarify, when I talk about 'previous communications between Master and Slave' and 'Everything else seems to work fine', I am referring to addressing the Slave with its unique address.
The only issue I seem to be getting, is when I try to send a command and data to the slave under General Call after I have read data from slave addressing it with its unique address value.


Sorry for any confusion.

Regards
Ttelmah



Joined: 11 Mar 2010
Posts: 19346

View user's profile Send private message

PostPosted: Wed Mar 30, 2011 8:43 am     Reply with quote

So are you following the full CGA standard?. Send the GCA, followed by '4', or '6' (the former says 'set the settable part of the address', while the latter says 'reset, and set this address'. The slave device to a GCA, is _required_ to ACK the bus, and wait for the second byte. A GCA, is not complete, till the second byte is sent. This is then followed by the 'programming sequence' (which you will have to define), designed to send the addresses in such a way that chips will each get a unique address.

Best Wishes
Steve Smith



Joined: 30 Mar 2011
Posts: 6
Location: Hampshire

View user's profile Send private message

PostPosted: Wed Mar 30, 2011 9:25 am     Reply with quote

Thanks again. I will look at the spec more closely for General Call.

However, if I pause my code (running in MPLAB Debugger) straight after I send Start then 00 (general call), the R/W bit in SSPSTAT is still a 1. Surely this bit should be a 0?

Regards
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