Detecting TWI stop condition on atMega

Go To Last Post
13 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The atMega nicely generates interrupts for all TWI conditions - as far as I can see - except for stop.

 

Is there a way to detect a stop condition that does not involve polling?

 

To send messages with small gaps in between the messages, or to send a read after a write, the only solution I have found is a busy loop which polls TWSR.

 

Is there a more elegant way to do this that I have overlooked?

 

All thoughts appreciated.

 

Thanks

Greg

regards
Greg

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Have you studied how Fleury handles such things?

 

(Fleury's I2C lib is perhaps the most widely used/highly respected library there is for I2C on AVR: http://www.peterfleury.epizy.com... (I2C is under "AVR-GCC libraries"))

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the quick response.

 

The Fleury code is all polled - unless there is another version. It is great for getting started as it is pretty much foolproof.

Detecting the stop condition is as below.

// wait until stop condition is executed and bus released
while(TWCR & (1<<TWSTO));

I have not been able to find an interrupt-based equivalent, but am hoping that someone has come up with a clever idea over the years.

Thanks

Greg

regards
Greg

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


gregd99 wrote:
The atMega nicely generates interrupts for all TWI conditions - as far as I can see - except for stop.
But the datasheet (I picked 328P - you didn't say which model of AVR) says:

 

also:

 

So what makes you say that STOP is not a source of TWINT ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Polling is the only way to test for STOP in Master mode.

 

What is the problem?

You either read TWCR or you wait for the specified time according to bus speed.

 

Of course you can't perform a STOP if the Slave is stretching SCL.

 

What are you trying to do?

Regular Slaves receive or send data to the Master according to the Master wiggling the SCL line.

When traffic is concluded the Master releases the bus with a STOP.

 

Certain Slaves will not ACK their Slave address when busy.   e.g. 24Cxx EEPROMs during a page-write.

Other chips might ACK but you have to monitor whether they are busy e.g. waiting for ADC to complete.

 

Life is much simpler if you quote the part number of a particular I2C chip.

Note that I2C is a protocol.  Different hardware chips have different internal operation.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the quick comments.

 

The master I am using is indeed a 328P. Apologies for not stating this.

The extract from the data sheet refers to an int for a stop for a slave. I am interested in the master side. This was probably not completely clear either.

 

I plan to poll - 2 byte tx, 2 byte rx - a set of 10 slaves (attiny85) within a 10 msec window. Even with loose wires on my workbench, 200kb/s is working fine (surprised about that! Need t look at the waveforms.) So the tx time is relatively short. A busy loop with timeout can work fine. It just seems a bit of a miss that there is not an int-based solution, and I was wondering whether there were some smarter ideas out there. An old, old discussion on the same issue below.

 

https://www.avrfreaks.net/forum/twi-stop-condition-avr315-bug

regards
Greg

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

gregd99 wrote:
I plan to poll - 2 byte tx, 2 byte rx - a set of 10 slaves

If you have only 1 master, do you need any stops? Just use repeated starts maybe ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So far I am using Interrupt only on Slave side. Not Master- which, btw. can be real or simulated.

 

Did I miss something? Why Master should have interrupts, please.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

First off.  You need to set out your objectives.

 

1.  does the Master do other jobs?

2.  do the Slaves do other jobs?

3.  how fast are your Slaves?

 

Be realistic. 

<S><1_W><D><D><S><1_R><D><D>

<S><2_W><D><D><S><2_R><D><D>

<S><3_W><D><D><S><3_R><D><D>

<S><4_W><D><D><S><4_R><D><D>

<S><5_W><D><D><S><5_R><D><D>

<S><6_W><D><D><S><6_R><D><D>

<S><7_W><D><D><S><7_R><D><D>

<S><8_W><D><D><S><8_R><D><D>

<S><9_W><D><D><S><9_R><D><D>

<S><10_W><D><D><S><10_R><D><D><P>

 

Is 60 I2C bytes with 20 Start and one Stop.   i.e. about 5600us of traffic @ 100kHz bus without any clock stretching.

 

Your Master can use interrupts.   And handle a lot of other stuff in that 5.6ms window.

The Slaves can handle a 400kHz bus but will be clock stretching dependent on their interrupt latency.   e.g. whatever else they are doing.

 

I can't see how you could possibly handle that amount of traffic on a 200kHz bus.

 

Ok.   if the write data is the same for each Slave you could use a General Call Address.

 

As I said at the beginning.   You need to specify what you actually want to do.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

• Bit 5 – TWSTA: TWI START Condition Bit The application writes the TWSTA bit to one when it desires to become a Master on the 2-wire Serial Bus. The TWI hardware checks if the bus is available, and generates a START condition on the bus if it is free. However, if the bus is not free, the TWI waits until a STOP condition is detected, and then generates a new START condition to claim the bus Master status. TWSTA must be cleared by software when the START condition has been transmitted.

I do not know, but maybe there is no need to wait for the stop to complete. You do the stop, continue on, eventually do another start (soon), the start command is accepted but the internal twi engine first waits for the bus to be free (sees a stop, which happens to be the one its generating), then does the start. You do not know any different because you are waiting for twint, and any waiting for stop is included.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

curtvm wrote:
I do not know, but maybe there is no need to wait for the stop to complete. You do the stop, continue on, eventually do another start (soon), the start command is accepted but the internal twi engine first waits for the bus to be free (sees a stop, which happens to be the one its generating), then does the start. You do not know any different because you are waiting for twint, and any waiting for stop is included.

+1

 

FF = PI > S.E.T

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

From memory you definitely need to wait for the Stop to complete.  But as McKendo suggested.   You can just do RepeatedStart.    There is only one Master so you don't need to release the bus.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

curtvm wrote:

 

I do not know, but maybe there is no need to wait for the stop to complete. You do the stop, continue on, eventually do another start (soon), the start command is accepted but the internal twi engine first waits for the bus to be free (sees a stop, which happens to be the one its generating), then does the start. You do not know any different because you are waiting for twint, and any waiting for stop is included.

 

 

This seems to work (328P)! It makes the code a little simpler and avoids wasted time! Thanks for a great suggestion.

As data are read back from the slave, there is an int on the last byte rx'ed and this can be used to trigger the receive processing, and next message.

 

The restarts idea should work in theory as well.

I thought about that but think that the handling of error conditions might get pretty ugly. e.g. 10 devices polled... something went wrong. which one was it? might then need to swing back to individual polling to find the problem child... and then the same problem (perhaps solved above) is present.

 

As to application.... the idea is to have a master device uc which monitors and drives a set of sensors/indicators on a model train layout. These data are communicated with a host computer which is automating the operation of the trains on the layout. The slave devices are driving IR detectors which detect train presence at various points on the layout. All good fun, and nothing life critical. If sensors lock up then things do crash :-)

 

It is more to keep my hand in with things technical while work takes me in some interesting.... but other directions.

 

Thanks for all the suggestions.

Greg

 

Thanks for

regards
Greg

Last Edited: Tue. Apr 19, 2022 - 11:36 PM