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

I2C multimaster. Switching PIC between Master and Slave.

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
kender



Joined: 09 Aug 2004
Posts: 768
Location: Silicon Valley

View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger

I2C multimaster. Switching PIC between Master and Slave.
PostPosted: Sun Jan 13, 2008 8:10 pm     Reply with quote

Colleagues,

Is it possible to choose between Master and Slave modes on the fly by writing to the SSPCON register?

I will have two PICs in the system. One will handle the display, another one will control the process. When the process isn’t running, the display PIC should be the Master. When the process is running, the display PIC should display the parameters. But the problem is that I have a requirement from the guy, who developed the current version of the control PIC firmware, that the control PIC shouldn’t be interrupted for serial communication. I’m contemplating about making a multimaster bus, where the process control PIC is a Master, when the process is running, and the display PIC is a Master for the rest of the time. I’ll probably add a handshaking line too. Do you think that this is a good approach?

Another option would be to replace I2C with CAN, which is a peer-to-peer bus to begin with.

Cheers,
- Nick
_________________
Read the label, before opening a can of worms.
kender



Joined: 09 Aug 2004
Posts: 768
Location: Silicon Valley

View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger

PostPosted: Sun Mar 09, 2008 4:56 pm     Reply with quote

Here's a code library thread on a similar subject. http://www.ccsinfo.com/forum/viewtopic.php?t=33950
It shows how to configure a PIC as a hardware slave on one pair of pins (SCL & SDA) and a software master on another pair. These two connections can go to the same I2C bus, and as a result the PIC can act as both master and slave on the same bus (at the expense of committing another pair pins).
_________________
Read the label, before opening a can of worms.
kender



Joined: 09 Aug 2004
Posts: 768
Location: Silicon Valley

View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger

Compiler acts strange, when it sees a second #use i2c
PostPosted: Sat Sep 06, 2008 4:06 pm     Reply with quote

Revisiting this area. First, I've looked at the assembly code generated by the #use i2c directive and found some instructions that configure the SSP control registers. Then I thought - may be #use i2c directive can be used multiple times to reconfigure the SSP peripheral. I tried that, but the compiler acted strangely.

Here's my test code:
Code:

while (1)
{
   #use i2c(Master, Fast, sda=PIN_C4, scl=PIN_C3, force_hw)      // become a master temporarily

   // dummy i2c transaction
   i2c_start();
   i2c_write(0xA0);
   i2c_stop();

   #use i2c(Slave, sda=PIN_C4, scl=PIN_C3, address=0xA0, FORCE_HW, NO_STRETCH)   // become a slave again
   delay_ms(1000);
   output_toggle(POWER_LED);  // show lifesigns
}


Here's the assembly listing:
Code:

....................    while (1)
....................    {
....................       #use i2c(Master, Fast, sda=PIN_C4, scl=PIN_C3, force_hw)      // become a master for
*
00CE:  BCF    FC6.7
00D0:  BCF    F9E.3
00D2:  MOVFF  1A,FC9
00D6:  MOVLW  02
00D8:  BTFSC  FC6.7
00DA:  BRA    00E6
00DC:  BTFSS  F9E.3
00DE:  BRA    00DC
00E0:  MOVLW  00
00E2:  BTFSC  FC5.6
00E4:  MOVLW  01
00E6:  MOVWF  01
00E8:  GOTO   017A (RETURN)
....................       i2c_start();
*
016E:  BSF    FC5.0
0170:  BTFSC  FC5.0
0172:  BRA    0170
....................       i2c_write(0xA0);
0174:  MOVLW  A0
0176:  MOVWF  1A
0178:  BRA    00CE
....................       i2c_stop();
017A:  BSF    FC5.2
017C:  BTFSC  FC5.2
017E:  BRA    017C
....................       #use i2c(Slave, sda=PIN_C4, scl=PIN_C3, address=0xA0, FORCE_HW, NO_STRETCH)   // become a slave again
....................       
....................       
....................       delay_ms(1000);
0180:  MOVLW  04
0182:  MOVWF  1A
0184:  MOVLW  FA
0186:  MOVWF  1B
0188:  RCALL  00A8
018A:  DECFSZ 1A,F
018C:  BRA    0184
....................       output_toggle(POWER_LED);  // blink
018E:  BCF    F96.2
0190:  BTG    F8D.2
....................    }




As you can see, the compiler had ignored the second #use i2c. It didn't generate an error or a warning. When I ran my code, it didn't execute past the i2c_stop() line. The PIC froze there.

When #use i2c(slave,...) is replaced with #use i2c(master,...) the compiler still ignores it, but the PIC doesn't freeze.

PCWH 4.071, PIC18F4525
_________________
Read the label, before opening a can of worms.
kender



Joined: 09 Aug 2004
Posts: 768
Location: Silicon Valley

View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger

... and that was only a beginning.
PostPosted: Sat Sep 06, 2008 11:29 pm     Reply with quote

Here's a more fundamental challenge. #use i2c directive defines the i2c_start(), i2c_stop(), i2c_read() and i2c_write(). The definitions are different for master and slave modes:

Code:
#use i2c(Master, Fast, sda=PIN_C4, scl=PIN_C3, force_hw)

....................       i2c_start();
020E:  BSF    FC5.0
0210:  BTFSC  FC5.0
0212:  BRA    0210
....................       i2c_write(0xA0);
0214:  MOVLW  A0
0216:  MOVWF  1A
0218:  BRA    00CE
....................       i = i2c_read();
021A:  MOVLW  01
021C:  MOVWF  00
021E:  BRA    00EC
0220:  MOVFF  01,19
....................       i2c_stop();
0224:  BSF    FC5.2
0226:  BTFSC  FC5.2
0228:  BRA    0226


Code:
#use i2c(Slave, sda=PIN_C4, scl=PIN_C3, address=0xA0, NO_STRETCH)

....................       i2c_start();
01E8:  BSF    F94.3
01EA:  BSF    F94.4
01EC:  BTFSS  F82.4
01EE:  BRA    01EC
01F0:  BTFSS  F82.3
01F2:  BRA    01F0
01F4:  BTFSC  F82.3
01F6:  BRA    01F0
01F8:  BCF    F94.3
01FA:  BCF    F8B.3
....................       i2c_write(0xA0);
01FC:  MOVLW  A0
01FE:  MOVWF  1A
0200:  BRA    00CE
....................       i = i2c_read();
0202:  BTFSS  FC7.0
0204:  BRA    0202
0206:  MOVFF  FC9,19
....................       i2c_stop();
020A:  BSF    F94.3
020C:  BSF    F94.4


So, to have a PIC that can switch between being a master and a slave, one should have two separate sets of read and write routines (e.g. i2c_slave_read(), ...).

BTW, what would i2c_start() in slave mode do? Should an I2C slave ever start a transaction?
_________________
Read the label, before opening a can of worms.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Sun Sep 07, 2008 3:02 am     Reply with quote

I wouldn't except, that the CCS built-in functions provide the discussed functionality of alternative master and slave operation. But the underlying PIC hardware is capable of it without doubt. So it is available by direct register programming.
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