|
|
View previous topic :: View next topic |
Author |
Message |
Ed Arnold Guest
|
i2c slave with HW #INT_SSP |
Posted: Wed Oct 23, 2002 6:42 am |
|
|
<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
|
Re: i2c slave with HW #INT_SSP |
Posted: Wed Oct 23, 2002 9:26 am |
|
|
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 |
Posted: Fri Oct 25, 2002 3:15 am |
|
|
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 |
|
|
|
|
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
|