|
|
View previous topic :: View next topic |
Author |
Message |
mlosso1
Joined: 21 Mar 2006 Posts: 9
|
Implementing general call addressing |
Posted: Thu Mar 23, 2006 2:12 pm |
|
|
I am looking to implement general call addressing by I2C with a 16F876A. How would I go about implementing this, per the description in the PIC datasheet:
Quote: | The addressing procedure for the I2C bus is such that the first byte after the Start condition usually determines which device will be the slave addressed by the master. The exception is the general call address which can address all devices. When this address is used, all devices should, in theory, respond with an Acknowledge. The general call address is one of eight addresses reserved for specific purposes by the I2C protocol. It consists of all ‘0’s with R/W = 0. The general call address is recognized when the General Call Enable bit (GCEN) is enabled (SSPCON2<7> set). Following a Start bit detect, 8 bits are shifted into
the SSPSR and the address is compared against the SSPADD. It is also compared to the general call address and fixed in hardware. If the general call address matches, the SSPSR is transferred to the SSPBUF, the BF flag bit is set (eighth bit) and on the falling edge of the ninth bit (ACK bit), the SSPIF interrupt flag bit is set. When the interrupt is serviced, the source for the interrupt can be checked by reading the contents of the SSPBUF. The value can be used to determine if the address was device specific or a general call address. In 10-bit mode, the SSPADD is required to be updated for the second half of the address to match and the UA bit is set (SSPSTAT<1>). If the general call address is sampled when the GCEN bit is set, while the slave is configured in 10-bit Address mode, then the second half of the address is not necessary, the UA bit will not be set and the slave will begin receiving data after the
Acknowledge (Figure 9-15). |
|
|
|
Ttelmah Guest
|
|
Posted: Thu Mar 23, 2006 3:39 pm |
|
|
Use standard I2C code, but add extra tests:
Code: |
int8 state;
int8 addr;
static int1 flag=false;
state=I2C_ISR_STATE;
if (flag) {
//Here you are receiving the second byte of a GCA call.
//Handle, and reset the flag
}
else if ((state & 0xFE)==0) {
//Here I have either an address match, or a general call
addr=(read_I2C() & 0xFE);
if (addr==0) {
//Here the chip has received a general call address.
//On the _next_ received byte, test the nature of the call
//0x6 as the next byte, means 'read, and reset and slave address'.
//0x4 as the next byte, means 're-read slave address'.
//Any byte ending in a '1', means 'please contact me'.
flag=true;
}
else {
//Normal address match handling code here.
}
}
//Normal code for multiple byte transfers here.
|
Make sure you set the GCEN bit in the hardware register for the chip.
You need to put the 'rest' of the function round this, and add the operations to perfom, but this shows how to detect the GCA.
Best Wishes |
|
|
mlosso1
Joined: 21 Mar 2006 Posts: 9
|
|
Posted: Thu Mar 23, 2006 9:38 pm |
|
|
We are using code pre i2c_isr_state |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 24, 2006 12:02 am |
|
|
Quote: | We are using code pre i2c_isr_state. |
Do you mean your version of the compiler doesn't support it ?
If so, here's some code that will emulate it. Add this code above main():
Code: |
#if defined __PCH__
#byte SSPSTAT = 0xFC7
#byte SSPBUF = 0xFC9
#elif defined __PCM__
#byte SSPSTAT = 0x94
#byte SSPBUF = 0x13
#endif
#bit DA_BIT = SSPSTAT.5
#bit RW_BIT = SSPBUF.0
#inline
int8 my_i2c_isr_state(void)
{
static int8 i2c_state = 0x03;
int8 retval;
if(!DA_BIT) // If address byte was received
{
i2c_state = 0; // Then clear state.
if(RW_BIT) // If it is a Read address
bit_set(i2c_state, 7); // Then set bit 7 of state.
}
retval = i2c_state;
i2c_state++;
return(retval);
}
|
Then put your i2c isr here. Call the my_i2c_isr_state() function
at the start of the isr. The value returned by the function is as
described in the current CCS manual.
Code: |
#int_ssp
void int_ssp_isr(void)
{
int8 state;
state = my_i2c_isr_state();
// Put other i2c slave code here.
}
|
|
|
|
Guest
|
|
Posted: Tue Apr 04, 2006 3:06 am |
|
|
Quote: | //0x6 as the next byte, means 'read, and reset and slave address' |
can some explain this a little bit more. i think i have the jist, but just want to make sure. |
|
|
Ttelmah Guest
|
|
Posted: Tue Apr 04, 2006 4:57 am |
|
|
I suggest you read the Philips I2C spec. Versions of this are easily downloadable on the web. The 'meaning' of a GCA call, is determined by the byte that follows it. Obviously, there is nothing potentially, to stop you from using GCA for your own uses, but if you are trying to produce a genuinely I2C compatible slave, then you are required to either ignore a GCA (if your device does not support it), or to follow the spec...
Best Wishes |
|
|
mlosso1
Joined: 21 Mar 2006 Posts: 9
|
|
Posted: Tue Apr 04, 2006 11:46 am |
|
|
This is from spec sheet:
Quote: | 00000110 (H‘06’). Reset and write programmable part
of slave address by hardware. On receiving this 2-byte
sequence, all devices designed to respond to the
general call address will reset and take in the
programmable part of their address. Pre-cautions have
to be taken to ensure that a device is not pulling down
the SDA or SCL line after applying the supply voltage,
since these low levels would block the bus.
· 00000100 (H‘04’). Write programmable part of slave
address by hardware. All devices which define the
programmable part of their address by hardware (and
which respond to the general call address) will latch this
programmable part at the reception of this two byte
sequence. The device will not reset.
|
What does it mean to take in the programmable part of their address? When they say Write programmable part does that mean, they will read in whatever the master sends in from the 2nd byte on? |
|
|
mlosso1
Joined: 21 Mar 2006 Posts: 9
|
|
Posted: Tue Apr 04, 2006 7:58 pm |
|
|
anyone's help or understanding would be greatly appreciated :D! |
|
|
Ttelmah Guest
|
|
Posted: Wed Apr 05, 2006 2:43 am |
|
|
If you look at a standard I2C memory part, they have a fixed address occupying the top 'nibble' of the address byte, and then three bits defined by switches. The GCA (06), tells them to read these three bits (the programmable part of the address), and then to do a reset, or not (04).
Devices do not normally read the address from the switches, when powered up, but only when power is applied, or when a GCA is sent.
No, it does not imply the ability to change an address using software, since GCA, addresses _all_ the devices on the bus, and if you sent a software address, this would result in all the devices changing together!...
GCA in this form, allows 'on the fly' reconfiguring, without having to switch off the system. It's commonest 'use' though, is the other form (I want servicing), which allows faster responses when devices have a change.
Best Wishes |
|
|
mlosso1
Joined: 21 Mar 2006 Posts: 9
|
|
Posted: Wed Apr 05, 2006 11:12 am |
|
|
Basically you are saying that using the other method, in which on the second byte (after the general call byte), is the most common one? This would be the method in which the LSB is 1, by my understanding, the PIC just wants to be serviced? Ttelmah, thanks in advance for all your help. |
|
|
mlosso1
Joined: 21 Mar 2006 Posts: 9
|
|
Posted: Fri Apr 07, 2006 12:13 am |
|
|
OK, my code essentially, because we are using an older version of the compiler, checks the status of the bits in the SSPSTAT Register to determine what state we are in. For the first state, which is the address has just been recieved state, I check to see if the address is all 0000s, and if so, then I set a general call flag. I am guessing the next thing I need to do, is edit the "Data recieved" state to check whether it is the any of the options mentioned above, and if so, do whatever based on those? |
|
|
Ttelmah Guest
|
|
Posted: Fri Apr 07, 2006 2:38 am |
|
|
Yes.
In the 'read' routine, check if the GCA flag is set, and if so treat the data byte as the 'command' byte for the GCA call.
Best Wishes |
|
|
eskimobob
Joined: 07 Feb 2009 Posts: 40
|
|
Posted: Tue Nov 16, 2010 9:08 am |
|
|
PCM programmer wrote: | If so, here's some code that will emulate it.
Call the my_i2c_isr_state() function
at the start of the isr. The value returned by the function is as
described in the current CCS manual.
|
I've just been whacked by this i2c_isr_state problem on a PIC16F1826 using compiler V4_099. It's taken me a lot of head scratching convince myself that i2c_isr_state code is faulty but when I found your post here I was very relieved to know I was not going mad.
I use it on several other PIC18F devices so it must be something peculiar to PCM compiler.
Anyway thanks for the workaround which works beautifully |
|
|
|
|
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
|