View previous topic :: View next topic |
Author |
Message |
gpfont1
Joined: 04 Jul 2007 Posts: 2
|
Switching I2C Master to Slave ..possible? |
Posted: Mon Apr 25, 2011 3:50 pm |
|
|
I have 2 processors talking to each other via I2C. Processor A is master and Processor B is slave. This is working well.
I'd like to flip them, where processor B is master and processor A is slave.
Is this possible? I've tried with multiple #use i2c statements but one thing I notice in the list file is that no writes to the specific i2c registers are generated when adding the #use i2c statements in the main code.
When Processor B supposedly becomes master and attempts to write to Processor A (which became slave), I'm not even getting an interrupt on Processor A.
Thank you for your assistance. |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Tue Apr 26, 2011 12:44 am |
|
|
Your application requires to change I2C mode dynamically. This functionality can't be provided by #use i2c.
You have to perform the respective SFR initialization manually. |
|
|
gpfont1
Joined: 04 Jul 2007 Posts: 2
|
|
Posted: Tue Apr 26, 2011 1:46 am |
|
|
Thanks.. I've tried (unsuccessfully). Are there any examples of this?
Regards. |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Tue Apr 26, 2011 3:36 am |
|
|
Quote: | Are there any examples of this? |
I fear, no. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Tue Apr 26, 2011 4:07 am |
|
|
Realistically, 'why bother?.
If you have even one signal wire free on the chips, then just add a wire so the 'slave' can send a signal to the 'master', saying 'take this data', and then the master can read it from the slave.
It is possible to change master to slave, but it will add code bulk (probably means you will need an interrupt handler in both chips), and code to deal with possible bus collisions.
There have been examples posted in the past, for 'multi-master' I2C, which will include parts of what you need, but I have had to do similar things in the past, end in one case, eventually decided it was going to be much easier and reliable to use RS485, and standard serial code, while in one dual chip case implemented a separate 'read me' wire. Working out how to get truly reliable bus collision detection on I2C, was more work than it was worth....
Best Wishes |
|
|
barryg
Joined: 04 Dec 2006 Posts: 41
|
|
Posted: Fri Sep 02, 2011 1:55 pm |
|
|
Practical application for Slave/Master switching. In this scenario, the PIC is a slave in a larger system. The system contains a computer running Windows, that is supposed to be the i2c master. However, the PIC controls the power! With Windows shut down, there is still power to run the PIC and some other peripherals. Now, we need the PIC to operate those devices because it's the only intelligent thing on the bus. The good part is that there isn't an issue with collisions, because the PIC knows darn well when the computer isn't running!
Here's what I did to make this work.
After some investigation, I found out some things about how CCS implements i2c. Part of making this easy is that CCS prefers to bit bang i2c master mode. (I happen to prefer this, too :) Slave mode uses interrupts, and this is almost mandatory because you have only microseconds to react when the master addresses you. (Though, proper clock stretching can alleviate this requirement).
- #USE I2C(MASTER... doesn't generate any init code. It just determines the port pins to be used in performing a bit-banging master. Somewhere, it will float the two appropriate lines, but that may be part of the routine code.
- #USE I2C(SLAVE...generates init code that precedes main(). Placing another #USE somewhere else in the code does not cause any kind of "switching" to occur; what it does is add another identical init section to the one that's already there ahead of main().
Knowing this, I suggest placing one #use/slave line at the "top" of main() (either before it or soon after the function starts), and placing the #use/master line(s) in with the code that actually implements the master section.
To switch from Slave to Master, do the following:
- Turn off the interrupt for the (M)SSP.
- Turn off the (M)SSP by clearning the SSPEN bit in the SSPxCON1 register.
- The master code should work normally.
To switch from Master to Slave:
- Turn on the (M)SSP by setting SSPxCON1.SSPEN
- Enable the interrupts for the (M)SSP.
As usual, a lot of work to get there, and then the implementation is pretty simple. |
|
|
anhthuc
Joined: 04 Dec 2011 Posts: 2
|
|
Posted: Sun Dec 04, 2011 4:37 am |
|
|
Can you post your CCS program, Barryg? |
|
|
facosta.ie
Joined: 29 Nov 2016 Posts: 5
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Fri Dec 02, 2016 5:39 pm |
|
|
Without knowing all the details..just what's being presented...
In Barryg's example, I don't consider the PC to be the 'master' as he says the PIC controls the power. As such, the PIC is the 'puppet master', the real computer in charge. Without that PIC, nothing can happen.
In the OP, I can't see any reason to switch the master/slave setup on the 'network'. It is after all only TWO devices. There should of course be some protocol setup for 'loss of communications' between the two devices but changing master/slave to slave /master won't accomplish that.
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Sat Dec 03, 2016 3:22 am |
|
|
As a comment:
#USE I2C(SLAVE...
Add 'NOINIT' to this, and it won't generate the init code.
When you want it:
I2C_init(TRUE);
Will generate the init code, and enable the hardware.
Generally I2C defaults to using the software. The only reason it uses the hardware when you select 'slave', is it cannot generate slave code in software. FORCE_HW selects to use the hardware in either mode.
The original post here pre-dates the I2C_init feature being available. |
|
|
|