View previous topic :: View next topic |
Author |
Message |
gil.fonea@sds-tech.com
Joined: 24 Mar 2010 Posts: 24
|
losing i2c buffers |
Posted: Thu Mar 25, 2010 4:59 am |
|
|
I am using a 18F86J90 as slave with the following i2c interrupt code:
Code: |
#INT_SSP
void ssp_interupt()
{
setup_oscillator(OSC_8MHZ);
i2c_state = i2c_isr_state();
if (i2c_state >= 0x80)
{
i2c_read(); //read address //master requests data
i2c_write(send_buffer[i2c_state - 0x80]); //preload xmit data
}
else if(i2c_state >= 0)
rcv_buffer[i2c_state] = i2c_read(); //master sends data
i2c_flag = 1; //for main loop
}
|
The first state I receive in this interrupt is 3 (I put a printf and while(1) to view the first state). This means that I lost 3 bytes
Why? Is my code wrong? Is there any known bug?
THX _________________ Gil F. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19549
|
|
Posted: Thu Mar 25, 2010 6:16 am |
|
|
Ignoring anything else, you don't want to be changing the oscillator rate inside an ISR.
You only want to select oscillator rates:
1) At the starts of the code.
2) If using low power sleep modes.
If you are doing the latter, and the chip is actually running at a much lower clock rate, then this is the problem. It takes typically 30+ instruction cycles to reach the ISR handler, and at a low clock rate, this is plenty of time to lose earlier characters...
Best Wishes |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Thu Mar 25, 2010 8:23 am |
|
|
I've learned that timing is rather critical in I2C communications. You need to make sure that your master is not sending commands/data faster than your slave can handle them. When the master sends an address out to the bus you need to give the slave time to realize that it's being talked to and to get ready. You can try to have your slave use clock stretching to tell the master to wait. If you have an oscilloscope, it would be very useful in tracking down your bus signals. Also, don't have your slave doing a printf() in the ISR. printf() takes a lot of time and your ISR can't be tied up with that.
Try placing a delay after each command, in your master, and see if that gets things working like you want. Play with clock stretching. Search the forum for these things. There have been many posts in I2C here.
Ronald |
|
|
|