|
|
View previous topic :: View next topic |
Author |
Message |
rudy
Joined: 27 Apr 2008 Posts: 167
|
i2c stretch clock |
Posted: Sun Feb 28, 2010 7:16 pm |
|
|
Hi all.
I am using one 16F877A @ 20MHz as Master and two other 16F877A @ 20 MHz as Slaves, and I work with 8 bytes of data between them.
Sometimes, the Master asks something to one Slave and the Slaves have to give back the answer.
In my Master routine, I have to insert a 1ms delay line to have time to acquire the proper answer generated by the Slaves and I'd like to avoid this using the stretch clock feature.
How can I do this? It's just a matter of putting a flag before the i2c_write() function on the Slave, so, when the data is ready, the Slave sets this flag and the Slave can send the bytes? The codes are:
Master
Code: |
.
.
.
i2c_xmt(2);
i2c_xmt(4);
delay_ms(1); //don't want to use the delay
i2c_rx(2);
.
.
.
|
Slaves:
Code: |
#INT_SSP
void SSP_isr()
.
.
state=i2c_isr_state();
if(state>=0x80)i2c_write(buffer[state-0x80]); // May I put a flag here to only allow Slave to Transmit when data is ready ?
else if(state>0)buffer[state-1]=i2c_read();
if(state==0x07)flag_0=1;
.
.
|
|
|
|
Ttelmah Guest
|
|
Posted: Mon Mar 01, 2010 6:10 am |
|
|
1mSec, suggests that are major problems in your receiver. I'd suspect you have a very slow handler for another interrupt, or large sections of code with interrupts disabled. Normal delay needed, is in the order of 100 instruction times, so at 20MHz, perhaps 20uSec.
Clock stretching, is the default. It is controlled by the flags 'NO_STRETCH', and 'DATA_HOLD' in the #use I2C setup. However on most chips, if the buffer is empty, and a byte is received, the ACK, is not stretched. Only some allow ACK to be held, till the byte is read (which is what you want). I think the 877, is too old to support this....
Best Wishes |
|
|
rudy
Joined: 27 Apr 2008 Posts: 167
|
|
Posted: Mon Mar 01, 2010 6:25 am |
|
|
Ok,
In fact 1ms is too much; I am only trying to finalize the I2C routine to further soon use.
What I want is that when the slave receive the address with R/W=1, the SCL line be held low, so, when I finish calculations, the proper routine that will be handling the data will release the SCL, by setting CKP=1.
My routine is working so well that I can live with this undesired delay, but, if I can do it using the stretch clock, will be better.
Further, the master will be replaced by an 18F4550, when I arrange some money to buy another recorders that’s support it.
Best for all. |
|
|
Ttelmah Guest
|
|
Posted: Mon Mar 01, 2010 9:33 am |
|
|
It should already be doing so, but if you want to make sure, simply set the SEN bit.
So:
Code: |
#byte SSPCON2=0x91
#byte SSPCON=0x14
#bit SEN=SSPCON2.0
#bit CKP=SSPCON.4
//Then in your main, before using the I2C, simply add
SEN=TRUE;
//And in your interrupt handler, add
CKP=TRUE;
//immediately after you load the byte to transmit (and after
//the reads for transfers the other way)
|
Best Wishes |
|
|
rudy
Joined: 27 Apr 2008 Posts: 167
|
|
Posted: Mon Mar 01, 2010 10:06 am |
|
|
Already done this, the slaves get lock when i set SEN bit.
Wonder why? |
|
|
Ttelmah Guest
|
|
Posted: Mon Mar 01, 2010 10:38 am |
|
|
1) The slave _always_ implements an automatic clock stretch on transmit mode. Setting SEN, enables this for reception (where it shouldn't normally be needed, provided you always read the buffer ASAP....).
2) Because of '1', what you describe should not be happening. You do realise, that you have to load the first 'return' byte, in the _same_ interrupt transaction, that received the address, with the write bit low?. This transaction, needs to _read_ this byte, and then immediately load the return data, 'in advance' of the master reading it. The read must also be present.
3) What you describe with 'SEN', would only happen, if there has been a byte received, and not handled. The slave will then hold the ACK, and because the handler is not called, will hang indefinately.
Best Wishes |
|
|
rudy
Joined: 27 Apr 2008 Posts: 167
|
|
Posted: Mon Mar 01, 2010 12:57 pm |
|
|
Ok.
Ok, I understand. It's not clear to me, now, is when do I need to clear CKP.
The fact is that, the buffer on slave is the same (reception and transmission) so, I receive 8 bytes from MASTER I set a flag, then I have to work on this buffer. This is the moment or "period" that I have hold SCL low. After that, when I finish all calculations on the buffer, I want to release SCL, to start to send (MASTER to SLAVE) the buffer contents back.
When and how can I do this? |
|
|
Ttelmah Guest
|
|
Posted: Mon Mar 01, 2010 3:49 pm |
|
|
What you are talking about, is not 'ack stretching', but physically taking over control of the line to stop the master sending anything else.
The hardware functions are not designed for this. You do realise that while the line is held like this, the master will be frozen if you use the normal 'ack' handling....
I'd suggest 'rethinking' just a little. In the slave, let the actual transaction complete, and when the full packet is seen, turn off the I2C peripheral, and drive the clock line low.
Then when the handling is complete, release the line, and turn the I2C peripheral back on.
In the master, since the transaction completes, it won't be hung, but then before initiating any I2C transaction, have it test that the clock line is high, _before_ commencing. This way the master can continue operating normally, right up to the point where it wants to send more data, and only stop here if the slave is busy.
Best Wishes |
|
|
rudy
Joined: 27 Apr 2008 Posts: 167
|
|
Posted: Mon Mar 01, 2010 4:50 pm |
|
|
I'm not totally convinced about, due to the master sends the address plus RW=1 with ACk on first byte.
But, like I said before, 1 ms delay is nothing to my MASTER routine, and I can live with it.
I just want to reduce the 1ms for minimum time to SLAVE work around the buffer values.
Thanks for now.
Best regards. |
|
|
|
|
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
|