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

slave holding SCL LOW!

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







slave holding SCL LOW!
PostPosted: Wed Apr 17, 2002 7:06 am     Reply with quote

hi,

i am using a EMICROS FLASH 12c232 to help develope this i2c communication within the 16f877,slave, i am able to send data(byte) to the 16f877 and have that data be written to portD where its connected to an LED array,its works fine. i am using PMC C 3.082

heres my trouble, i want the slave to send back specific data bytes base on what the master asks. right now i am testing for 1 byte at a time. when the master sends a request to read, i can see the address-R/W-not/ack on the oscope but after the ningth clock, the SCL is held low forever.

so i understand it to be a valid address and the pic is acking it, i believe the pic is hold it low and this is what i dont understand, i write to SSPBUF and set CKP then exit the isr as the literature stated, here is my code:



#include "includes\16F877.H" //CCS HEADER
#include "includes\16F877MC.H" //MICROCHIP HEADER

#fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP
#use delay(clock=4000000)
#use I2C(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0xa0)

typedef enum {START, ADDRESS_READ, READ, WRITE} I2C_STATE;

I2C_STATE nextState=START;

byte incoming = 0x00,
address = 0x00,
command = 0x00,
errorCount = 0x00,
temp = 0x00;


#int_ssp
void ssp_interupt (){

if(i2c_poll() == TRUE){
incoming = i2c_read();

switch(nextState){
case START:
nextState = START;
address = incoming;
//if(bit_test(*_SSPSTAT, _WRITE)){
//nextState = WRITE;
//i2c_write(0xAA);
_SSPBUF = 0xAA;
bit_set(*_SSPCON, _CKP);
//bit_clear(*_PIR1, _SSPIF);
//}
//else nextState = READ;
break;
case READ:
nextState = START;
command = incoming;
break;
case WRITE:
nextState = START;
command = 0xFF;
i2c_write(0xAA);
_SSPBUF = 0xAA;
bit_set(*_SSPCON, _CKP);
bit_clear(*_PIR1, _SSPIF);

break;
default:
nextState = START;
break;
}
}
}


void main() {

#use fast_io(d)
set_tris_d(0x00);
#use fast_io(e)
set_tris_e(0x00);

enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);

while (TRUE) {
output_d(address);
delay_ms(1500);
output_d(command);
delay_ms(1500);
}
}

any help would be greatly apreciated!
___________________________
This message was ported from CCS's old forum
Original Post ID: 3834
Tomi
Guest







Re: slave holding SCL LOW!
PostPosted: Wed Apr 17, 2002 10:39 am     Reply with quote

I don't think that a slave can hold down the SCL line. Take a look on Figure 9-10 (Page#71): in the slave mode SCL is an input-only line.

One important thing is that i2c_poll() returns true only if you have a RECEIVED byte. It could be a control or address byte or a data byte to store. To read out the slave you will get an IT without a pending data. See "ex_slave.c" for an i2c slave example:
if (i2c_poll() == FALSE) {
if (fState == ADDRESS_READ) { //i2c_poll() returns false on the
i2c_write (buffer[address]);//interrupt receiving the second
fState = NOTHING; //command byte for random read operation
}
}



:=hi,
:=
:=i am using a EMICROS FLASH 12c232 to help develope this i2c communication within the 16f877,slave, i am able to send data(byte) to the 16f877 and have that data be written to portD where its connected to an LED array,its works fine. i am using PMC C 3.082
:=
:=heres my trouble, i want the slave to send back specific data bytes base on what the master asks. right now i am testing for 1 byte at a time. when the master sends a request to read, i can see the address-R/W-not/ack on the oscope but after the ningth clock, the SCL is held low forever.
:=
:=so i understand it to be a valid address and the pic is acking it, i believe the pic is hold it low and this is what i dont understand, i write to SSPBUF and set CKP then exit the isr as the literature stated, here is my code:
:=
:=
:=
:=#include "includes\16F877.H" //CCS HEADER
:=#include "includes\16F877MC.H" //MICROCHIP HEADER
:=
:=#fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP
:=#use delay(clock=4000000)
:=#use I2C(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0xa0)
:=
:=typedef enum {START, ADDRESS_READ, READ, WRITE} I2C_STATE;
:=
:=I2C_STATE nextState=START;
:=
:=byte incoming = 0x00,
:= address = 0x00,
:= command = 0x00,
:= errorCount = 0x00,
:= temp = 0x00;
:=
:=
:=#int_ssp
:=void ssp_interupt (){
:=
:= if(i2c_poll() == TRUE){
:= incoming = i2c_read();
:=
:= switch(nextState){
:= case START:
:= nextState = START;
:= address = incoming;
:= //if(bit_test(*_SSPSTAT, _WRITE)){
:= //nextState = WRITE;
:= //i2c_write(0xAA);
:= _SSPBUF = 0xAA;
:= bit_set(*_SSPCON, _CKP);
:= //bit_clear(*_PIR1, _SSPIF);
:= //}
:= //else nextState = READ;
:= break;
:= case READ:
:= nextState = START;
:= command = incoming;
:= break;
:= case WRITE:
:= nextState = START;
:= command = 0xFF;
:= i2c_write(0xAA);
:= _SSPBUF = 0xAA;
:= bit_set(*_SSPCON, _CKP);
:= bit_clear(*_PIR1, _SSPIF);
:=
:= break;
:= default:
:= nextState = START;
:= break;
:= }
:= }
:=}
:=
:=
:=void main() {
:=
:= #use fast_io(d)
:= set_tris_d(0x00);
:= #use fast_io(e)
:= set_tris_e(0x00);
:=
:= enable_interrupts(GLOBAL);
:= enable_interrupts(INT_SSP);
:=
:= while (TRUE) {
:= output_d(address);
:= delay_ms(1500);
:= output_d(command);
:= delay_ms(1500);
:= }
:=}
:=
:=any help would be greatly apreciated!
___________________________
This message was ported from CCS's old forum
Original Post ID: 3841
Bob McWilliams
Guest







Re: slave holding SCL LOW!
PostPosted: Wed Apr 17, 2002 11:15 am     Reply with quote

The Slave WILL hold the clock line low until it can process the data. This is documented in the PIC's data sheet under the I2C specifications.

One thing that I noticed in your code is inside the SWITCH statement(case WRITE). You call I2C_WRITE(), which stuffs SSPBUF with the data to transmit, then you manually stuff SSPBUF
with another byte of data. This may/will cause an OVERFLOW condition, in which case the SSP needs to be reset.

I'm sorry but I'm not as apt at I2C communication using CCS's I2C commands, I like to code it all out myself.
___________________________
This message was ported from CCS's old forum
Original Post ID: 3843
jetlang
Guest







Re: slave holding SCL LOW!
PostPosted: Wed Apr 17, 2002 11:43 am     Reply with quote

:=The Slave WILL hold the clock line low until it can process the data. This is documented in the PIC's data sheet under the I2C specifications.
:=
:=One thing that I noticed in your code is inside the SWITCH statement(case WRITE). You call I2C_WRITE(), which stuffs SSPBUF with the data to transmit, then you manually stuff SSPBUF
:=with another byte of data. This may/will cause an OVERFLOW condition, in which case the SSP needs to be reset.
:=
:=I'm sorry but I'm not as apt at I2C communication using CCS's I2C commands, I like to code it all out myself.


the switch statement case WRITE: should not happen becuase i use "//" to comment out code so i can test reading from the pic16f877 with just case START and that it should happen in just one trigger of INT that is for one byte read. the case WRITE is for 1+x bytes read.

from figure 9-7 p.76, once the address byte is recieved and INT is trigger on the nineth clock, we enter the ISR, so i go ahead and verify there is a byte-using i2c_poll(), which i think is redundant, then read in the address using i2c_read(), and then process to write to the SSPBUF with data then enable the CKP and exit ISR - like from figure 9-7 illustrates


enter isr:
f(i2c_poll() == TRUE){
incoming = i2c_read();

address = incoming;
_SSPBUF = 0xAA;
bit_set(*_SSPCON, _CKP);
exit isr:

thanks,
___________________________
This message was ported from CCS's old forum
Original Post ID: 3846
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

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

Re: slave holding SCL LOW!
PostPosted: Wed Apr 17, 2002 11:45 am     Reply with quote

Yes the slave will hold the SCL line low (its called clock stretching) in order for the PIC to have time to process the int.

Mark
:=I don't think that a slave can hold down the SCL line. Take a look on Figure 9-10 (Page#71): in the slave mode SCL is an input-only line.
:=
:=One important thing is that i2c_poll() returns true only if you have a RECEIVED byte. It could be a control or address byte or a data byte to store. To read out the slave you will get an IT without a pending data. See "ex_slave.c" for an i2c slave example:
:= if (i2c_poll() == FALSE) {
:= if (fState == ADDRESS_READ) { //i2c_poll() returns false on the
:= i2c_write (buffer[address]);//interrupt receiving the second
:= fState = NOTHING; //command byte for random read operation
:= }
:= }
:=
:=
:=
:=:=hi,
:=:=
:=:=i am using a EMICROS FLASH 12c232 to help develope this i2c communication within the 16f877,slave, i am able to send data(byte) to the 16f877 and have that data be written to portD where its connected to an LED array,its works fine. i am using PMC C 3.082
:=:=
:=:=heres my trouble, i want the slave to send back specific data bytes base on what the master asks. right now i am testing for 1 byte at a time. when the master sends a request to read, i can see the address-R/W-not/ack on the oscope but after the ningth clock, the SCL is held low forever.
:=:=
:=:=so i understand it to be a valid address and the pic is acking it, i believe the pic is hold it low and this is what i dont understand, i write to SSPBUF and set CKP then exit the isr as the literature stated, here is my code:
:=:=
:=:=
:=:=
:=:=#include "includes\16F877.H" //CCS HEADER
:=:=#include "includes\16F877MC.H" //MICROCHIP HEADER
:=:=
:=:=#fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP
:=:=#use delay(clock=4000000)
:=:=#use I2C(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0xa0)
:=:=
:=:=typedef enum {START, ADDRESS_READ, READ, WRITE} I2C_STATE;
:=:=
:=:=I2C_STATE nextState=START;
:=:=
:=:=byte incoming = 0x00,
:=:= address = 0x00,
:=:= command = 0x00,
:=:= errorCount = 0x00,
:=:= temp = 0x00;
:=:=
:=:=
:=:=#int_ssp
:=:=void ssp_interupt (){
:=:=
:=:= if(i2c_poll() == TRUE){
:=:= incoming = i2c_read();
:=:=
:=:= switch(nextState){
:=:= case START:
:=:= nextState = START;
:=:= address = incoming;
:=:= //if(bit_test(*_SSPSTAT, _WRITE)){
:=:= //nextState = WRITE;
:=:= //i2c_write(0xAA);
:=:= _SSPBUF = 0xAA;
:=:= bit_set(*_SSPCON, _CKP);
:=:= //bit_clear(*_PIR1, _SSPIF);
:=:= //}
:=:= //else nextState = READ;
:=:= break;
:=:= case READ:
:=:= nextState = START;
:=:= command = incoming;
:=:= break;
:=:= case WRITE:
:=:= nextState = START;
:=:= command = 0xFF;
:=:= i2c_write(0xAA);
:=:= _SSPBUF = 0xAA;
:=:= bit_set(*_SSPCON, _CKP);
:=:= bit_clear(*_PIR1, _SSPIF);
:=:=
:=:= break;
:=:= default:
:=:= nextState = START;
:=:= break;
:=:= }
:=:= }
:=:=}
:=:=
:=:=
:=:=void main() {
:=:=
:=:= #use fast_io(d)
:=:= set_tris_d(0x00);
:=:= #use fast_io(e)
:=:= set_tris_e(0x00);
:=:=
:=:= enable_interrupts(GLOBAL);
:=:= enable_interrupts(INT_SSP);
:=:=
:=:= while (TRUE) {
:=:= output_d(address);
:=:= delay_ms(1500);
:=:= output_d(command);
:=:= delay_ms(1500);
:=:= }
:=:=}
:=:=
:=:=any help would be greatly apreciated!
___________________________
This message was ported from CCS's old forum
Original Post ID: 3847
jetlang
Guest







Re: slave holding SCL LOW!
PostPosted: Wed Apr 17, 2002 11:52 am     Reply with quote

<font face="Courier New" size=-1>:=I don't think that a slave can hold down the SCL line. Take a look on Figure 9-10 (Page#71): in the slave mode SCL is an input-only line.
:=
:=One important thing is that i2c_poll() returns true only if you have a RECEIVED byte. It could be a control or address byte or a data byte to store. To read out the slave you will get an IT without a pending data. See "ex_slave.c" for an i2c slave example:
:= if (i2c_poll() == FALSE) {
:= if (fState == ADDRESS_READ) { //i2c_poll() returns false on the
:= i2c_write (buffer[address]);//interrupt receiving the second
:= fState = NOTHING; //command byte for random read operation
:= }
:= }

this example i really cant understand, i think it conflicts with figure 9-7 p.76, it shows that there was 1 INT occured(the address read) before the 2nd INT to write the data out, so a total to 2 INT.

what i think should happen is, that when address is recieved, on the 9th clock the INT happends, then invokes ISR, thus in the SSPBUFF is the address along with the R/W_not, so the address is stored and write to SSPBUF with data and re-enable SLC,all in one INT

thanks,</font>
___________________________
This message was ported from CCS's old forum
Original Post ID: 3850
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

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

Re: slave holding SCL LOW!
PostPosted: Wed Apr 17, 2002 11:54 am     Reply with quote

How is _SSPBUF declared? The same way as _SSPCON. Like
#define _SSPBUF 0x13

if so then you need the following
*_SSPBUF = 0xAA;
instead of
_SSPBUF = 0xAA;

I have also found that the compiler now treats this as a 16bit number so actually you will have to cast it:
(int)*_SSPBUF = 0xAA;

Let me know if this helps. I did not go through the code very well. I usually don't use CCS's built in functions simply because they tend to get "broken".

Mark


:=hi,
:=
:=i am using a EMICROS FLASH 12c232 to help develope this i2c communication within the 16f877,slave, i am able to send data(byte) to the 16f877 and have that data be written to portD where its connected to an LED array,its works fine. i am using PMC C 3.082
:=
:=heres my trouble, i want the slave to send back specific data bytes base on what the master asks. right now i am testing for 1 byte at a time. when the master sends a request to read, i can see the address-R/W-not/ack on the oscope but after the ningth clock, the SCL is held low forever.
:=
:=so i understand it to be a valid address and the pic is acking it, i believe the pic is hold it low and this is what i dont understand, i write to SSPBUF and set CKP then exit the isr as the literature stated, here is my code:
:=
:=
:=
:=#include "includes\16F877.H" //CCS HEADER
:=#include "includes\16F877MC.H" //MICROCHIP HEADER
:=
:=#fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP
:=#use delay(clock=4000000)
:=#use I2C(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0xa0)
:=
:=typedef enum {START, ADDRESS_READ, READ, WRITE} I2C_STATE;
:=
:=I2C_STATE nextState=START;
:=
:=byte incoming = 0x00,
:= address = 0x00,
:= command = 0x00,
:= errorCount = 0x00,
:= temp = 0x00;
:=
:=
:=#int_ssp
:=void ssp_interupt (){
:=
:= if(i2c_poll() == TRUE){
:= incoming = i2c_read();
:=
:= switch(nextState){
:= case START:
:= nextState = START;
:= address = incoming;
:= //if(bit_test(*_SSPSTAT, _WRITE)){
:= //nextState = WRITE;
:= //i2c_write(0xAA);
:= _SSPBUF = 0xAA;
:= bit_set(*_SSPCON, _CKP);
:= //bit_clear(*_PIR1, _SSPIF);
:= //}
:= //else nextState = READ;
:= break;
:= case READ:
:= nextState = START;
:= command = incoming;
:= break;
:= case WRITE:
:= nextState = START;
:= command = 0xFF;
:= i2c_write(0xAA);
:= _SSPBUF = 0xAA;
:= bit_set(*_SSPCON, _CKP);
:= bit_clear(*_PIR1, _SSPIF);
:=
:= break;
:= default:
:= nextState = START;
:= break;
:= }
:= }
:=}
:=
:=
:=void main() {
:=
:= #use fast_io(d)
:= set_tris_d(0x00);
:= #use fast_io(e)
:= set_tris_e(0x00);
:=
:= enable_interrupts(GLOBAL);
:= enable_interrupts(INT_SSP);
:=
:= while (TRUE) {
:= output_d(address);
:= delay_ms(1500);
:= output_d(command);
:= delay_ms(1500);
:= }
:=}
:=
:=any help would be greatly apreciated!
___________________________
This message was ported from CCS's old forum
Original Post ID: 3851
jetlang
Guest







Re: slave holding SCL LOW!
PostPosted: Wed Apr 17, 2002 1:24 pm     Reply with quote

:=How is _SSPBUF declared? The same way as _SSPCON. Like
:=#define _SSPBUF 0x13
:=
:=if so then you need the following
:=*_SSPBUF = 0xAA;
:=instead of
:=_SSPBUF = 0xAA;
:=
:=I have also found that the compiler now treats this as a 16bit number so actually you will have to cast it:
:=(int)*_SSPBUF = 0xAA;
:=
:=Let me know if this helps. I did not go through the code very well. I usually don't use CCS's built in functions simply because they tend to get "broken".
:=
:=Mark
:=

hey mark,

_SSPBUF and others are declared as #bytes, well i found that if i read data u using i2c_read() somehow hold SLC low in my code, so i read from _SSPBUF instead, now i have a clock after the firstbyte but the data i loaded into _SSPBUF is not xfering out, maybe i have to set SDA to output now.
___________________________
This message was ported from CCS's old forum
Original Post ID: 3858
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

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

Re: slave holding SCL LOW!
PostPosted: Wed Apr 17, 2002 2:07 pm     Reply with quote

If they are #byte then

bit_set(*_SSPCON, _CKP);
bit_clear(*_PIR1, _SSPIF);

should not be using pointer notation. You should use
bit_set(_SSPCON, _CKP);
bit_clear(_PIR1, _SSPIF);

_CKP & _SSPIF should be #define


Mark

:=:=How is _SSPBUF declared? The same way as _SSPCON. Like
:=:=#define _SSPBUF 0x13
:=:=
:=:=if so then you need the following
:=:=*_SSPBUF = 0xAA;
:=:=instead of
:=:=_SSPBUF = 0xAA;
:=:=
:=:=I have also found that the compiler now treats this as a 16bit number so actually you will have to cast it:
:=:=(int)*_SSPBUF = 0xAA;
:=:=
:=:=Let me know if this helps. I did not go through the code very well. I usually don't use CCS's built in functions simply because they tend to get "broken".
:=:=
:=:=Mark
:=:=
:=
:=hey mark,
:=
:=_SSPBUF and others are declared as #bytes, well i found that if i read data u using i2c_read() somehow hold SLC low in my code, so i read from _SSPBUF instead, now i have a clock after the firstbyte but the data i loaded into _SSPBUF is not xfering out, maybe i have to set SDA to output now.
___________________________
This message was ported from CCS's old forum
Original Post ID: 3860
Kam Yip
Guest







Re: slave holding SCL LOW!
PostPosted: Wed Apr 17, 2002 9:03 pm     Reply with quote

I've similar experience using I2C_Poll routines. To minimise your pain, pls avoid using this routine because u have no idea what is happening. I have done my own routine for slave I2C receive and it is working well! U can refer to the 16c78 datasheet for some guideline.
___________________________
This message was ported from CCS's old forum
Original Post ID: 3864
jetlang
Guest







Re: slave holding SCL LOW!
PostPosted: Thu Apr 18, 2002 6:18 am     Reply with quote

:=I've similar experience using I2C_Poll routines. To minimise your pain, pls avoid using this routine because u have no idea what is happening. I have done my own routine for slave I2C receive and it is working well! U can refer to the 16c78 datasheet for some guideline.


found that out the hard way, thus i am re-coding everything myself, besides i learn i2c much more that way, thanks,
___________________________
This message was ported from CCS's old forum
Original Post ID: 3876
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