|
|
View previous topic :: View next topic |
Author |
Message |
valemike Guest
|
Ready to give up with CCS's i2c slave libraries |
Posted: Mon May 10, 2004 3:42 pm |
|
|
I'm trying to implement a Slave hardware I2C. Even Microchip's FAEs say there are issues with CCS's slave i2c, as i read the same here every now now and then also.
Looking at this sample code, from the Master:
Code: |
#include <18F252.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use i2c(Master,sda=PIN_C4,scl=PIN_C3)
void main()
{
byte incoming;
while (1)
{
i2c_start();
i2c_write(0xa0); //slave can read.
i2c_write(incoming);
i2c_write(5);
i2c_write(0x01); // slave can write.
delay_ms(1);
// if (i2c_poll())
// {
incoming = i2c_read();
incoming = i2c_read();
// }
// i2c_stop();
}
}
|
As you can see, I commented out the i2c_poll() and the i2c_stop, and just keep looping. When I try to issue an i2c_read() at the master, then it causes the slave to trigger an i2c_read() of 0xFF.
Is the i2c_read() up above supposed to block until the slave issues an i2c_write()? I don't seem to see that happening.
I don't know if CCS's i2c library (especially for PICs acting as i2c slaves) is robust, and i'm ready to ditch using the library and instead manipulating the the control registers directly.
Here's the slave code below. heck for some reason, i can't seem to get an i2c_poll() to return a TRUE when issuing an i2c_read() shortly after the master issued an i2c_start(). So i figure, the heck with the i2c_poll(), and just do an i2c_read() everytime i get an SSP interrupt. That seems to work just fine for reads, but then i can't do a write. oh well. |
|
|
Haplo
Joined: 06 Sep 2003 Posts: 659 Location: Sydney, Australia
|
|
Posted: Mon May 10, 2004 5:30 pm |
|
|
er...you forgot to post the slave code. |
|
|
Darren Rook
Joined: 06 Sep 2003 Posts: 287 Location: Milwaukee, WI
|
|
Posted: Mon May 10, 2004 6:40 pm |
|
|
Use FORCE_HW, else it's using SW on the master. |
|
|
Darren Rook
Joined: 06 Sep 2003 Posts: 287 Location: Milwaukee, WI
|
Re: Ready to give up with CCS's i2c slave libraries |
Posted: Mon May 10, 2004 7:03 pm |
|
|
valemike wrote: |
Is the i2c_read() up above supposed to block until the slave issues an i2c_write()? I don't seem to see that happening.
|
Yes, in hardware mode i2c_read() sets the RCEN bit in SSPCON2 and then waits indefinately until RCEN is cleared by hardware. RCEN is cleared by hardware when it receives a byte.
If you're so convinced that it's CCS's fault how about some proof? |
|
|
valemike Guest
|
slave and master code |
Posted: Tue May 11, 2004 8:52 am |
|
|
I apologize yesterday for quickly pointing the finger at CCS's i2c library. With so many different scenarios, there is no way their example code can exactly fit a programmer's needs unless the programmer understanding what is going on.
Anyways, I tried using FORCE_HW at the master. Here is the example code:
master:
Code: |
#include <18F252.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use i2c(Master,sda=PIN_C4,scl=PIN_C3, FORCE_HW)
void main()
{
byte incoming;
while (1)
{
i2c_start();
i2c_write(0xa0); //slave can read.
delay_ms(100);
i2c_write(5);
delay_ms(100);
i2c_write(0x01); // slave can write.
while (i2c_poll() == FALSE)
{
}
incoming = i2c_read();
i2c_stop();
}
}
|
And the SLAVE code:
Code: |
#include <18F452.h>
#fuses HS,NOWDT,NoPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use I2C(slave, sda=PIN_C4, scl=PIN_C3, address=0xa0, FORCE_HW)
typedef enum
{
ADDRESS_READ,
DATA_READ
} I2C_STATE;
I2C_STATE fState;
BYTE address, buffer[0x10];
volatile int flag;
byte incoming;
#INT_SSP
void i2c_slave_handler(void)
{
incoming = i2c_read();
flag = 1;
}
void main(void)
{
int i;
flag = 0;
fState = ADDRESS_READ;
for (i=0; i<0x10; i++)
buffer[i] = 0x00;
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
printf ("Start i2c slave\r\n");
while (1)
{
if (flag == 1)
{
printf ("incoming = 0x%2.2X\r\n", incoming);
flag = 0;
if (incoming == 0x01)
{
i2c_write(0x01);
flag = 0;
}
}
}
}
|
The output on Hyperterminal looks like this:
Code: |
Start i2c slave
incoming = 0xA0
incoming = 0x05
incoming = 0x01
|
I have a ICE2000 running on the master. I see that it never gets past the while (i2c_poll() == FALSE). I have ICD-2 running on the slave. I see that it does get past the i2c_write() when incoming == 0x01. However, the Master never sees its i2c_poll go TRUE.
This is getting really frustrating. |
|
|
|
|
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
|