![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
future
Joined: 14 May 2004 Posts: 330
|
i2c master/slave, 2 pic and an eeprom |
Posted: Wed Oct 08, 2008 4:01 pm |
|
|
Hi,
I am building a device that has 2 pic and an eeprom in the same i2c bus. The code works until I write to the other device, for example:
Master Pic.
Code: | #use i2c(MASTER, SDA=PIN_C4, SCL=PIN_C3, FORCE_HW)
int1 i2c_ready (char device) {
int1 ack;
i2c_start(); // If the write command is acknowledged,
ack = i2c_write(device); // then the device is ready.
i2c_stop();
return !ack;
}
// readings from the i2c bus
// S=start
// 60=address
// A=ack
// P=stop
i2c_ready(0x60); // S 60 A P
i2c_ready(0x60); // S 60 A P
i2c_ready(0x60); // S 60 A P
i2c_ready(0x60); // S 60 A P
i2c_ready(0xA0); // S A0 A P
i2c_ready(0xA0); // S A0 A P
i2c_ready(0x60); // S 60 N P
i2c_ready(0xA0); // S A0 A P |
The slave pic works fine until I send something to another address, then it will nak forever.
slave pic:
Code: | char read_i2c(void);
void i2c_interrupt_handler(void);
void i2c_initialize(void);
void write_i2c(unsigned char transmit_byte);
#INT_SSP
void ssp_interupt () {
i2c_interrupt_handler();
}
#define RX_BUF_LEN 64
#define NODE_ADDR 0x60 /* I2C address of the slave node (avoid addr masking) */
unsigned char slave_buffer[RX_BUF_LEN];
int buffer_index;
int comms_error;
int debug_state;
void i2c_initialize (void) {
debug_state = 0;
/* Set up SSP module for 7-bit */
while (SSPCON2 & 0x1F); // ACKEN RCEN PEN RSEN SEN all must be zero
SSPSTAT = 0x00; /* Clear the SSPSTAT register. */
SSPCON1 = 0x36; /* 0011 0110 */
SSPADD = NODE_ADDR; /* Set the slave's address */
/* init buffers */
buffer_index = 0;
enable_interrupts(INT_SSP); /* Enable MSSP interrupts. */
}
void i2c_interrupt_handler (void) {
unsigned char temp_sspstat;
unsigned char this_byte;
unsigned char tx_byte;
int x;
/* Mask out the unnecessary bits */
temp_sspstat = SSPSTAT & 0x2D; /* 0010 1101 */
switch (temp_sspstat)
{
case 0x09: /* 0000 1001 */ /* Write operation, last byte was an address, buffer is full */
buffer_index = 0; /* Clear the buffer index */
this_byte = read_i2c(); /* Do a dummy read of PIC_SSPBUF */
debug_state = 1;
break;
case 0x29: /* 0010 1001 */ /* Write operation, last byte was data, buffer is full */
this_byte = read_i2c(); /* Get the byte from the SSP */
slave_buffer[buffer_index] = this_byte; /* Put it into the buffer */
buffer_index++; /* Increment the buffer pointer */
debug_state = 2;
break;
case 0x0D: /* 0000 1101 */ /* Read operation; last byte was address, buffer is full */
this_byte = read_i2c(); /* Do a dummy read of PIC_SSPBUF to clear it */
// while(SSPSTATbits.BF);
case 0x0C: /* 0000 1100 */ /* Read operation; last byte was an address, buffer is empty */
buffer_index = 0; /* Clear the buffer index */
tx_byte = slave_buffer[buffer_index]; /* Get byte from the buffer */
write_i2c(tx_byte); /* Write the byte to PIC_SSPBUF */
buffer_index++; /* increment the buffer index */
debug_state = 3;
break;
case 0x2C: /* 0010 1100 */ /* Read operation; last byte was data, buffer is empty */
tx_byte = slave_buffer[buffer_index];
write_i2c(tx_byte); /* Write to PIC_SSPBUF */
buffer_index++; /* increment the buffer index */
debug_state = 4;
break;
case 0x28: /* 0010 1000 */ /* A NACK was received when transmitting data back [to] the master. */
debug_state = 5; /* Slave logic is reset in this case. R_W=0, D_A=1, and BF=0. */
break; /* If we don't stop in this state, then something is wrong!! */
default:
debug_state = 0xE;
break;
}
}
void write_i2c(unsigned char transmit_byte) {
unsigned char write_collision = 1;
while (SSPSTATbits.BF); /* Is BF bit set in PIC_SSPSTAT? */
while (write_collision)
{
/* If not, then do the i2c_write. */
SSPCON1bits.WCOL = 0; /* Clear the WCOL flag */
SSPBUF = transmit_byte;
/* Was there a write collision? */
if (SSPCON1bits.WCOL)
{
/* Yes there was a write collision. */
write_collision = 1;
}
else
{
/* NO, there was no write collision. */
/* The transmission was successful */
write_collision = 0;
}
}
SSPCON1bits.CKP = 1; /* Release the clock. */
}
/* This function returns the byte in SSPBUF */
unsigned char read_i2c(void) {
return SSPBUF;
} |
I can not see what I am doing wrong. Any tips would be welcome.
Thank you. |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Oct 08, 2008 4:22 pm |
|
|
1. Post your PICs and your compiler version.
2. Post the #fuses and #use delay() statements for both PICs.
3. Try it without the FORCE_HW on the master. |
|
![](templates/subSilver/images/spacer.gif) |
future
Joined: 14 May 2004 Posts: 330
|
|
Posted: Wed Oct 08, 2008 4:59 pm |
|
|
ok,
two 18f4620 running at 40mhz. compiler version 3.249.
master fuses:
#fuses H4,NOWDT,NOPROTECT,NOLVP
#use delay(clock=40000000)
#use i2c(MASTER, SDA=PIN_C4, SCL=PIN_C3, FORCE_HW)
slave fuses:
#fuses H4,NOWDT,NOPROTECT,NOLVP
#use delay(clock=40000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
the slave pic does not have the #use i2c directive because it does not use the compilerĀ“s library.
Using the software i2c didnĀ“t help. The communication seems to be fine but something at the end of transaction is left in a wrong state. |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Oct 08, 2008 5:11 pm |
|
|
1. Slow down your master. Change the H4 to HS, and change the
#use delay() to 10 MHz.
2. Put delays between the master's i2c statements.
If there is a problem where some process in the slave PIC doesn't have
time to finish, these tests will help to show it. |
|
![](templates/subSilver/images/spacer.gif) |
MicroManiac
Joined: 21 Aug 2008 Posts: 34
|
|
Posted: Thu Oct 09, 2008 3:23 am |
|
|
Try using the Force Software because i faced some problems with the Force hardware previously and when i used the force SW it worked fine _________________ "Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius -- and a lot of courage -- to move in the opposite direction."
Albert Einstein |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|