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 CCS Technical Support

Help needed - Changing modes in I2C

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



Joined: 19 Nov 2005
Posts: 5
Location: Devon, England

View user's profile Send private message Send e-mail

Help needed - Changing modes in I2C
PostPosted: Mon Jan 02, 2006 6:45 am     Reply with quote

Happy New year!!

No-one answered my question I posed before Christmas about changing between I2C Master and Slave modes at runtime.
Is it impossible, or does nobody know the answer?
I can't believe with all the code-writers out there that it hasn't been done.


I am using a PIC18F452 and for most of the time I want the PIC to act as a master on the i2c bus. Occassionally it needs to be a slave.
I initialise the i2c port with:
#use i2c(MASTER, sda=PIN_C4, scl=PIN_C3,FORCE_HW)
Later on in the code when I need to receive data from another device I try to change the I2c port by:
#use i2c(SLAVE, sda=PIN_C4, scl=PIN_C3, Address=0xA0)
But it doesn't work!! The PIC stays as a master.
If I look at the CCS listing there is no new code added where I want the change to take effect.
How do you change from master to slave and back again and why does the compiler ignore the directive?

grateful for any suggestions
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jan 02, 2006 2:29 pm     Reply with quote

Quote:
No-one answered my question I posed before Christmas about changing
between I2C Master and Slave modes at runtime. Is it impossible, or
does nobody know the answer?
I can't believe with all the code-writers out there that it hasn't been done.

I haven't done this, but no one else has responded so I've put
together a possible framework that might solve your problem.
You will have to fill in the missing code.

The key thing that you need to understand is that once you put
down a #use i2c() statement, all i2c library functions after that
that point will be configured according to the parameters specified
in the #use i2c() statement.

If you then put down another #use i2c() statement farther down
in the program, all i2c library functions after that point will
use the parameters specified in that statement. You can see how
I use this feature in the code below.

However, CCS does not really expect you to be doing this, so they
don't have routines that you can call, to init for master or slave mode.
They put code in there to do that, but it's part of the hidden init code
that they insert at the start of main(). In the program shown below,
only code for Master mode will be inserted by the compiler at the
start of main().

Because you want to switch between modes, you need to look at the
.LST file and determine which lines of ASM code are used to init the
master mode, and then essentially copy that code and put it into your
own master_i2c_init() routine.

To find out how CCS initializes the slave mode, you need to compile
their example program, EX_SLAVE.C, and do that same thing.
Look at the .LST file near the start of main() and copy the code and
put it into slave_i2c_init().

By "copy the code", I actually mean re-write it, by using direct register
access statements, and use #byte and #bit statements to define the
register and bit addresses. Also consult the PIC data sheet while doing
this.

Code:
#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

// The following 3 lines are from EX_SLAVE.C.
typedef enum {NOTHING, CONTROL_READ,
              ADDRESS_READ, READ_COMMAND_READ} I2C_STATE;

I2C_STATE fState;
BYTE address, buffer[0x10];


//---------------------------------
void master_i2c_init(void)
{
// Disable slave interrupts.
disable_interrupts(INT_SSP);
clear_interrupt(INT_SSP);

// Put code here to setup MSSP module for i2c master mode.
// Look in the PIC data sheet to find the proper registers.
// Use #byte and #bit directives to define the addresses
// of the registers.
// Also, look at the .LST file, to see how CCS initializes
// the master mode.  Copy what they do.
}

//---------------------------------
void slave_i2c_init(void)
{
// Put code here to setup MSSP module for i2c slave mode.
// Look in the PIC data sheet to find the proper registers.
// Use #byte and #bit directives to define the addresses
// of the registers.
// Also, look at the .LST file, to see how CCS initializes
// the slave mode.  Copy what they do.

// After doing that, enable interrupts for the slave.
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
}


//----------------------------------
#use i2c(Slave, sda=PIN_C4, scl=PIN_C3, address=0xA0, Force_HW)

#INT_SSP
void ssp_interupt ()
{

// Put isr code here from the CCS example file, EX_SLAVE.C

}


#use i2c(Master, sda=PIN_C4, scl=PIN_C3, Force_HW)

//=====================================
void main()

int8 result;
int16 address;

// Configure for Master mode.
master_i2c_init();

address = 0x0000;

// Master reads a byte from 24LC256 eeprom.
i2c_start();
i2c_write(0xA0);        // i2c write address
i2c_write(address >> 8);
i2c_write(address);
i2c_start();            // re-start
i2c_write(0xA1);        // i2c read address
result = i2c_read(0);   // Read with NACK
i2c_stop();         


// Configure for Slave mode.
slave_i2c_init();


while(1);
}
vetinaspin



Joined: 19 Nov 2005
Posts: 5
Location: Devon, England

View user's profile Send private message Send e-mail

Changing modes in I2C
PostPosted: Tue Jan 03, 2006 2:16 am     Reply with quote

Thanks for your reply.
I had hoped there was another solution but looking at the way the CCS compiler references the initial code I can see there is not. I know exactly what you are saying regarding the solution so I will go down this route.

Many thanks.
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