|
|
View previous topic :: View next topic |
Author |
Message |
Guest
|
i2c SLAVE issue |
Posted: Thu Jan 04, 2007 9:18 pm |
|
|
I have been trying to implement I2C interface for quite a long time, but it has all been in vain!!!
I am trying to talk to a MASTER that is not a microchip product. I am trying the use the Slave example in the CCS compiler on a PIC18F2520. I put a bunch of printf() statements for incoming byte and the state, and noticed that my code hangs in the I2C routine.
The reason I think for this is the way the master code is written. Below is the pseudo code for the master code:
MASTER
1. ID data Record:
start()
write(0x9C) //0x9C = WR
start()
write(0x9D) //0x9D = RD ID
data[3] = read(ACK)
data[2] = read(ACK)
data[1] = read(ACK)
data[0] = read(NACK)
stop()
2. Read short data record:
start()
write(0x9F) //0x9F = RD SHORT
data[12] = read(ACK)
...
data[1] = read(ACK)
data[0] = read(NACK)
stop()
3. Read long data record:
start()
write(0x9D) //0x9E = RD LONG
data[32] = read(ACK)
...
data[1] = read(ACK)
data[0] = read(NACK)
stop()
Master sends one of these 3 requests at a time.
I have an infinite for loop in my main method. In order to be able to feed the master with the required data. I disable the SSP and GLOBAL interrupts. And then Enable them when I have the data ready. And if I go into the interrupt I give the master the data as per request then, come out of the interrupt. Disable the interrupt and prepare the data for the next sequence.
I tend to hang in the interrupt for some reason.
If you notice the in 2 of the 3 cases the Master sends the Address of the slave and the control byte combined in one command. Where as the slave example code use the first command from the master for just matching the address, and then the second command from the master as the control byte.
Since I cannot change the code in the master, any suggestions as to how I can retrieve the address sent by the master in the first command.
Another big problem using the Slave code is that whenever I check for the STATE I always get 0x80 and whenever I check foe the incoming byte, I always get 0x9D. I have spent a lot of time trying to debug this.
Any Suggestions!!!!!! |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Thu Jan 04, 2007 9:57 pm |
|
|
My first suggestion would be to post the slave code. |
|
|
Guest
|
|
Posted: Fri Jan 05, 2007 2:08 pm |
|
|
Here is the code.
Code: |
# include <18f2520.h> // Contains all the defined variables for the Pic
# include <PScomp.h> // Contains all the definitions for the Project
#device adc=10 // 10 bit output
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4910000) // External Clock 4.91 MHz
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) // RS232 Settings
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3,FORCE_HW, address=0x9C)
void main()
{
for(;;)
{
disable_interrupts(GLOBAL);
disable_interrupts(INT_SSP);
// Here I have code to prepare all the data that needs to be sent to the master.
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
}
#INT_SSP
void ssp_interupt ()
{
BYTE incoming, state;
int i;
state = i2c_isr_state();
if(state = 0x80) //Master is Sending data
{
incoming = i2c_read();
if(incoming == 0x9D) // Master is Asking for the Firmware Identifier
{
for(i=0;i<4;i++)
{
i2c_write(IDpack[i]);
if(state >!(0x81))
{
i2c_stop();
}
}
}
}
if(incoming == 0x9D) // Here I need to actualy find the addess of the First command sent by the Mater instead of 'incoming'(I THINK SO!!)
{
for(i=0;i<33;i++)
{
i2c_write(IDpack[i]);
if(state >!(0x81))
{
i2c_stop();
}
}
}
if(incoming == 0x9F) //// Here I need to actualy find the addess of the First command sent by the Mater instead of 'incoming'(I THINK SO!!)
{
for(i=0;i<13;i++)
{
i2c_write(IDpack[i]);
if(state >!(0x81))
{
i2c_stop();
}
}
}
} |
I would really appreciate any help! |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Fri Jan 05, 2007 3:36 pm |
|
|
This is definitely wrong
if(state = 0x80) //Master is Sending data
I am not sure what you are trying to do here
if(state >!(0x81))
Lastly, if the I2C address of the slave is 0x9C then
start()
write(0x9F) //0x9F = RD SHORT
data[12] = read(ACK)
...
data[1] = read(ACK)
data[0] = read(NACK)
stop()
would never work since its I2C address would be 0x9E.
How do you know what the master is sending? What was used instead of a PIC before? |
|
|
Guest
|
|
Posted: Fri Jan 05, 2007 6:07 pm |
|
|
I agree with you. I have 3 different cases. The master polls me periodically with any of the three cases.
In the 1st case where the master asks for the ID data Record it sends a 0x9C then 0x9D. So here, I can have the ISR as:
Code: |
if(state < 0x80) // Master is sending data
{
incoming = i2c_read();
if(state == 1) // First received byte is address
address = incoming; // for a read or write operation.
if(incoming == 0x9D) // Master is Asking for the Firmware Identifier
{
for(i=0;i<4;i++)
{
i2c_write(IDpack[i]);
if(state >!(0x81))
{
i2c_stop();
}
}
}
}
|
But in case 2 and 3 the Master just writes once to the slave (0x9F and 0x9D respectively). I don’t know how to retrieve that one address the master wrote to the slave so I can know if it’s the 2nd or 3rd case the master is interested in.
As I understand since the device select bits (0x9) in this case remains the same from the master, the slave should respond. It’s the don’t care bits are the bits that are being changed by the master in order to make the slave respond differently.
Quote: |
Posted: Fri Jan 05, 2007 3:36 pm Post subject:
--------------------------------------------------------------------------------
I am not sure what you are trying to do here
if(state >!(0x81))
|
I read on the compiler help page that the state returns 0x81-0xFF if the transmission was acknowledged. So that’s why I thought of calling it after every i2c_write() from the slave.
The master is using Philips P87C51RC+4N.
I just have its pseudo code unfortunately!!! |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Sat Jan 06, 2007 12:33 pm |
|
|
Quote: | As I understand since the device select bits (0x9) in this case remains the same from the master, the slave should respond. It’s the don’t care bits are the bits that are being changed by the master in order to make the slave respond differently.
|
This is incorrect. The address bits are either 7 or 10 bits. For what you are suggesting, the address would have to be a 4 bit number.
If you don't have access to the master's code, then this leads me to believe that this must be an existing product that already has a slave device that works but you are now trying to emulate the existing slave device. What is the existing slave device? |
|
|
|
|
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
|