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 slave with HW #INT_SSP

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







i2c slave with HW #INT_SSP
PostPosted: Wed Oct 23, 2002 6:42 am     Reply with quote

<font face="Courier New" size=-1>Has anyone successfully got the CCS #use i2c() function to work in hardware slave mode. I have looked at the example ex_slave code, but I don't understand it. What am I missing? The MicroChip data sheet states the i2c hardware interrupts on an address match. So does this mean that the CCS ADDRESS parameter in #use i2c() puts your defined address into SSPADD.
Well anyway, when I run this code in a Master(F877)/ Slave(F873) situation, both pics lock up. I also have a DS1307 RTC and 24C64 eeprom on the same bus which run fine without this Slave(F873). Here is a sample of what I have written.

#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, ADDRESS=0xE0, FORCE_HW)

#INT_SSP
void ssp_interrupt()
{
while(!i2c_poll());
cmd = i2c_read(0);
return;
}

void main(void)
{
setup_adc_ports(NO_ANALOGS);
set_tris_a(0xFF);
set_tris_b(0x00); //all outputs
set_tris_c(0x18); //
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
LED=1;
while(1)
{
while(!cmd);
for(i=0;i<cmd;i++)
{
LED=0; //turn on led
delay_ms(200);
LED=1; //turn off led
delay_ms(500);
}

Thanks in advance for any help

Ed Arnold ___________________________
This message was ported from CCS's old forum
Original Post ID: 8114
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

Re: i2c slave with HW #INT_SSP
PostPosted: Wed Oct 23, 2002 9:26 am     Reply with quote

Are you writing to or reading from the slave. If you are reading from the slave then you will have to handle reenabling the clock. The clock is held low to allow time to load the transmission buffer. Also, you should not have the while statement in your ISR. That is the reason for using the interrupt. So you do not have to wait. You should also set cmd back to 0 in your test code in the main loop.
Here is some code that I use for slave receiving. This is actually used to receive a message and then send back an acknowlege or not acknowledge.

void ABUS_Rx_Byte(void)
{
static UINT8 rx_count = 0; /* num of bytes received */
static UINT8 rx_msg_len = 0; /* msg length */
static UINT8 checksum = 0; /* message checksum (XOR) */
static UINT8 data = 0; /* data read from SSPBUF */

/* Make sure the buffer has not overflowed */
if (bit_test(*SSPCON, SSPOV))
{
I2CStatus = (UINT8)*SSPBUF;
/* Clear the register */
bit_clear(*SSPCON,SSPOV);
I2CStatus = I2CIDLE;
return;
}

/* We recieved a stop bit so set our I2CStaus back to idle and clean
up. */
if (bit_test(*SSPSTAT,STOP_BIT))
{
I2CStatus = I2CIDLE;
Wait_Time = 1;
I2C_Timeout = 0;
}
else
{
/* were we addressed in read mode so set up for data to be read
from us - slave mode.
*/
if (bit_test(*SSPSTAT, READ_WRITE))
{
if (Rx_Msg.hdr.stat == CHECKSUM_OK)
{
Rx_Msg.hdr.stat = PROCESS_OK;
/* Load acknowledgement value */
(UINT8)*SSPBUF = MSGACK;
}
else
{
(UINT8)*SSPBUF = MSGNACK;
}
/* Setup to allow data to be read from us */
bit_set(*SSPCON, CKP);
I2CStatus = I2CSLAVETxING;
I2C_Timeout = 25;
rx_count = 1;
}
/* See if we were addressed */
/* The following line was modified because of errata with
the PIC18CXX2 clearing the BF bit when the BSR is pointed to 0x0F
and an instruction contains 0xC9 in its 8 least significant bits */
// else if (bit_test(*SSPSTAT,BF_BIT))
else if ((bit_test(*SSPSTAT,BF_BIT)) || (I2CStatus == I2CRxING))
{
/* continue recieving bytes */
/* process the first byte */
if (!bit_test(*SSPSTAT,ADDRESS_BIT))
{
/* Read the data */
data = (UINT8)*SSPBUF;
Turn_On_Abus_LED();
I2CStatus = I2CRxING;
Rx_Msg.hdr.stat = INVALID_MSG;
Rx_Msg.hdr.dest = data;
rx_msg_len = 2;
rx_count = 1;
checksum = data;
}
else
{
/* Read the data */
data = (UINT8)*SSPBUF;

/* keep track of how many bytes */
++rx_count;

/* test for length of msg byte */
if (rx_count == 3)
/* set length counter, ignore MSB*/
rx_msg_len = data & 0x7F;
else
--rx_msg_len;

/* check for end of msg. This occurs when our message length
reaches -1.
*/
if (rx_msg_len == -1)
{
I2CStatus = I2CWAITING;
if ((checksum ^ data) == 0)
Rx_Msg.hdr.stat = CHECKSUM_OK;
else
Rx_Msg.hdr.stat = INVALID_MSG;
}

/* The checksum is an XOR of all the data bytes */
checksum ^= data;

/* Store the data if our buffer in large enough */
if (rx_count < sizeof(Rx_Msg.buf))
Rx_Msg.buf[rx_count] = data;
}

/* Wait up to 25ms for another byte before we timeout */
I2C_Timeout = 25;
}
}
}

Note that I do not use the CCS functions. Also, the SFRs were defined using #define and that is the reason for the pointer notation.

Regards,
Mark

:= := Well anyway, when I run this code in a Master(F877)/ Slave(F873) situation, both pics lock up. I also have a DS1307 RTC and 24C64 eeprom on the same bus which run fine without this Slave(F873). Here is a sample of what I have written.
:=
:=#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, ADDRESS=0xE0, FORCE_HW)
:=
:=#INT_SSP
:=void ssp_interrupt()
:={
:= while(!i2c_poll());
:= cmd = i2c_read(0);
:= return;
:=}
:=
:=void main(void)
:={
:= setup_adc_ports(NO_ANALOGS);
:= set_tris_a(0xFF);
:= set_tris_b(0x00); //all outputs
:= set_tris_c(0x18); //
:= enable_interrupts(INT_SSP);
:= enable_interrupts(GLOBAL);
:= LED=1;
:= while(1)
:= {
:= while(!cmd);
:= for(i=0;i<cmd;i++)
:= {
:= LED=0; //turn on led
:= delay_ms(200);
:= LED=1; //turn off led
:= delay_ms(500);
:= }
:=
:=Thanks in advance for any help
:=
:=Ed Arnold ___________________________
This message was ported from CCS's old forum
Original Post ID: 8120
Jim van Zee
Guest







Re: i2c slave with HW #INT_SSP
PostPosted: Fri Oct 25, 2002 3:15 am     Reply with quote

There is also a minor issue re. the address= parameter: CCS just puts whatever you give it in SSPADD. Since this value must be an even number, if you say 'address=0x01' things won't work. I think they forgot to mention this...

Jim van Zee
:--------------------------------------------------------------
:=<font face="Courier New" size=-1>Has anyone successfully got the CCS #use i2c() function to work in hardware slave mode. I have looked at the example ex_slave code, but I don't understand it. What am I missing? The MicroChip data sheet states the i2c hardware interrupts on an address match. So does this mean that the CCS ADDRESS parameter in #use i2c() puts your defined address into SSPADD.
:= Well anyway, when I run this code in a Master(F877)/ Slave(F873) situation, both pics lock up. I also have a DS1307 RTC and 24C64 eeprom on the same bus which run fine without this Slave(F873). Here is a sample of what I have written.
:=
:=#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, ADDRESS=0xE0, FORCE_HW)
:=
:=#INT_SSP
:=void ssp_interrupt()
:={
:= while(!i2c_poll());
:= cmd = i2c_read(0);
:= return;
:=}
:=
:=void main(void)
:={
:= setup_adc_ports(NO_ANALOGS);
:= set_tris_a(0xFF);
:= set_tris_b(0x00); //all outputs
:= set_tris_c(0x18); //
:= enable_interrupts(INT_SSP);
:= enable_interrupts(GLOBAL);
:= LED=1;
:= while(1)
:= {
:= while(!cmd);
:= for(i=0;i<cmd;i++)
:= {
:= LED=0; //turn on led
:= delay_ms(200);
:= LED=1; //turn off led
:= delay_ms(500);
:= }
:=
:=Thanks in advance for any help
:=
:=Ed Arnold ___________________________
This message was ported from CCS's old forum
Original Post ID: 8181
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