CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

can anyone clarify how to use i2c_poll in i2c master mode?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
JamesW, Kent, England
Guest







can anyone clarify how to use i2c_poll in i2c master mode?
PostPosted: Fri May 15, 2009 5:24 am     Reply with quote

Hi Folks,

I finally managed to get hardware i2c working yesterday on my 18F4685. It turned out to be a combination of not setting the tris values of the relevant pins to inputs and the ccs wizard generated setup_spi(FALSE) which actually disables it!

Here's what I am trying to do....

Generate some code that in the event of some sort of i2c bus lockup (which has happened a couple of times using sofware i2c) recovers from it.

looking through the documentation on i2c the function i2c_poll() seems ideal.

So rather than just using i2c_read which could sit there forever, I can call poll_i2c() in a loop for a set number of times. If it returns true, great get the value using i2c_read otherwise attempt some sort of recovery.

However I cannot get i2c_poll() to work for love nor money!

I am only including the code snippet that is relevant and this isn't how I want to use it, but in order to prove that i2c_poll works this should be sufficient.


do
{

}while(!i2c_poll()) ;

data = i2c_read(0);
i2c_stop();


however the code only works when the i2c_poll loop is removed.

This kind of half makes sense, as reading the datasheet the ssp needs to know that it is in receive mode, before receieving data - and i2c_read seems to be the function that does this.

Should I be writing to a register before the i2c_poll call that tells the ssp that it should be looking for data? If so, what?


Any hints tips gratefully received!

Also any hints on i2c bus recovery would be gratefully received

Thanks

James
Ttelmah
Guest







PostPosted: Fri May 15, 2009 7:03 am     Reply with quote

Key thing to understand, is that in I2C, the _master_ generates the clocks.
I2C_POLL, goes 'true', when the chip's hardware buffer, has received a byte. This can never happen on a master, unless it has sent the clocks to get it....
Now, the only things that can really hang an I2C bus from the "master's" point of view, is if the slave device (or some electrical problem), has triggered an indefinate clock stretch, holding the clock line low. You can determine if this line is low, by simply reading the pin. Other things you can check in the master, are the WCOL bit, which can normally only go true in a multi master system, but can become set again by hardware problems.
If a slave device, has hung the bus, then you really need to add hardware implementation of an ability to reset the slave devices (master control of their reset lines), or if you control the code in them, software or watchdog timeouts in the slaves, forcing a bus reset.
Generally, I2C lockups, are less common, when external bus buffering is used, rather than direct drive from the PIC. Also, good signal clamping on the lines will help.
So, I2C_POLL, is not reallu of help in a master.

Best Wishes
JamesW, Kent, England
Guest







PostPosted: Fri May 15, 2009 7:42 am     Reply with quote

Thanks,

That kind of explains the problem.

Next question. I assume that scl is held low by the slave before I do the read from it?

So would sampling the SCL line and waiting in a loop for it to become high before commencing the read help solve this?

I'm trying to assertain at which point in an i2c read it can lock up, as at the moment it can just stop in the read, which means that it's too late to do anything about it( other than a watchdog reset, which seems really messy).

Thanks again

James
Ttelmah
Guest







PostPosted: Fri May 15, 2009 8:17 am     Reply with quote

The master generates all clocks, _but_ a slave, can 'hold' the SCL line low, on the last clock, while it is processing the data. Basically, this is called 'clock stretching', and is designed to allow time for the slave to get into the interrupt handler, and read the byte. The problem comes, if the slave does not release the line, since then the bus is effectively 'hung'. The master can't initiate a transaction, while the line is low...
Clock stretching, is controlled by the CKP bit, in the slave device, and it is _vital_ that this is set at the end of the interrupt routine.
Though watchdog timeout's are 'messy', they are also to some extent vital, if reliability is to be really good. Your design should be done with them disabled, and got to the point where reliability is as far as you can tell 100% without them, then the boot code should be setup to ensure that clean recovery will take place if they trigger, and the transaction protocol, and internal logic setup so a watchdog restart will always be reached if transactions are occurring. The watchdog, then becomes the 'belt and braces' recovery, if something goes wrong, because of a glitch...
A timeout, provides a 'less drastic' recovery without going this far. If (for instance), you have a timer 'tick' running, that just tests the clock line level, and it is found 'low' on a sequence of calls, then something basically has to be 'wrong', and resetting the I2C hardware, then becomes an option. If this is done at bolt ends of the link, hopefully you have the basis of recovery. Smile

Best Wishes
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Fri May 15, 2009 9:45 am     Reply with quote

You need to make sure that your bus signals are clean and noise free. Noise will cause erratic lock-ups. I _always_ use a device that helps sharpen the edges of each bus line. The one I like is the LTC-1694-1. Next, if your timing is not allowing the slave time to process things then this can cause lock-ups as well.

Try using a scope to see what your bus lines are doing. Make sure your master isn't sending commands too fast. And if you're using a PIC as a slave device, have it control the CKP bit so the master won't try to send commands too fast for it.

You want your code to run as quickly as possible but not so tight that any variance will cause things to lock up.

Ronald
Ttelmah
Guest







PostPosted: Fri May 15, 2009 3:08 pm     Reply with quote

Yes.
This is why I suggested external buffering, it makes a _huge_ difference to I2C reliability, especially if going 'off board'.

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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