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

i2c_isr_state

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



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

i2c_isr_state
PostPosted: Sat Jul 21, 2007 1:50 pm     Reply with quote

I'm working on an I2C master slave pair. If I send writes to the slave it behaves, but when I read it never acts like it see the read.

Here is the master code
Code:

 ////////////**************8Test code for master*********/////////////////////
relaynumber=1;
while(1)
{

            output_low(PIN_B7);
            BoardAddress=0x50;
            i2c_start();
            i2c_write(BoardAddress);     //Address
            delay_ms(15);
            i2c_write(20);              // command for pour           
            delay_ms(15);
            i2c_write(relaynumber);        // send relay num   
            delay_ms(15);
            i2c_write(4);         // send time to pour 
            delay_ms(15);
            i2c_stop();
            Output_high(PIN_B7);
            delay_ms(1500);
            relaynumber++;
            if(relaynumber>8)
                relaynumber=1;


            while(value==0)             // 0 means still working, 1 means finished
            {
                printf("asking slave board if it is finished\r\n");
                i2c_start();   // start condition
                i2c_write(BoardAddress + 1);
                value = i2c_read(0);
                i2c_stop();
//                delay_ms(500);             
            }



}
////////////**************8Test code for master*********/////////////////////



and here is the slave interrupt code

Code:

#INT_SSP
void ssp_interupt ()
{
    int i;
    BYTE incoming, state;
    donepouring=0;

   state = i2c_isr_state();
    printf("i2c state = %d\r\n",state);
   if(state < 0x80)                     //Master is sending data
   {
       if(state >0)//data not address
        {
            bytecounter++;
            if(bytecounter>42)// too many bytes, somethign is wrong
            {
                bytecounter=0;
                printf("i2c overflow\r\n");
                return;   
            }
          incoming = i2c_read();
          buffer[bytecounter] = incoming;
         
          if(bytecounter ==3 )                     //First received byte is address
            {
              if(buffer[1]==20)                             //pour command
              {
                  SERIAL_BUFFER[0]='p';
                  SERIAL_BUFFER[1]=' '; 
                  SERIAL_BUFFER[2]=49;                       //board address 
                  SERIAL_BUFFER[3]=':'; 
                  SERIAL_BUFFER[4]=buffer[2]+48;               // relay num
                  SERIAL_BUFFER[5]=':'; 
                  SERIAL_BUFFER[6]=buffer[3]+48;               // time
                  SERIAL_BUFFER[7]='\r'; 
                printf("I2c received");
                for(i=1;i<=3;i++)
                    printf(" %d ",buffer[i]); 
                printf("\r\n");

                printf("i2c sending command to pour  ");
                for(i=0;i<=7;i++)
                    putc(SERIAL_BUFFER[i]); 
                printf("\r\n");
                    bytecounter =0;
                  pour();
              }
            }
         
          if(bytecounter ==8 )                     //First received byte is address
            {
                for(i=1;i<=8;i++)
                    printf(" %x ",buffer[i]); 
                printf("\r\n");
                printf("buffer[8]= %d \r\n",buffer[8]);
                if((buffer[1]==0) && (buffer[2]==0xa0)
                    && (buffer[3]==0) && (buffer[4]==0xaa)
                    && (buffer[5]==0) && (buffer[6]==0xa5)
                    && (buffer[7]==0))
                {       
                    NODE_ADDR=buffer[8];
                    PIC_SSPADD=NODE_ADDR;// change address
                    write_EEPROM (0,NODE_ADDR);// save new address   
                    actionflag=2; //0 = nothing, 1 = read, 2 = change address
                }       
                bytecounter=0;
            }       
        }   
    }
   if(state == 0x80)                     //Master is requesting data
   {
      i2c_write(donepouring);
        output_low(PIN_B6);
        output_low(PIN_B7);
        delay_ms(100);
        output_high(PIN_B6);
        output_high(PIN_B7);
      actionflag=1; //0 = nothing, 1 = read, 2 = change address
   }
}



The master sends a command to the slave to activate a relay for a few seconds. As soon as the slave sees a command it sets donepouring=0; When it is finished a few seconds later it sets donepouring=1;
I would expect the master to loop until the slave is finished then move on. But if I take out the 1500ms delay in the mast loop then it does not work. Also b6, b7 never toggle on the slave so I think the state==0x80 is not firing.

the output from the printf's looks like this
i2c state = 0
i2c state = 1
i2c state = 2
i2c state = 3
I2c received 20 8 4
i2c sending command to pour p 1:8:4
pouring relay# 8 for 4 time
done pouring


The weird part to me is I have another master slave pair that only reads from the slave, and the interrupt code for 0x80 is the same and the read code is the same. Anybody see what I'm missing here? I could leave big delays in but would rather know when the lave is finished.

Thanks
Ringo
_________________
Ringo Davis
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Sun Jul 22, 2007 10:26 am     Reply with quote

I narrowed the problem down to this code.
Code:

            value=1;
            while(value==0)             // 0 means still working, 1 means finished
            {
                output_low(PIN_B6);
                delay_ms(500);             
                i2c_start();   // start condition
                i2c_write(BoardAddress + 1);
                value = i2c_read(0);
                i2c_stop();
                output_high(PIN_B6);
            }

The program always skips the code. It never enters the wile loop. It executes code before and after it. If I change the while loop to a for loop it executes the code. Any ideas why this would happen?
I'm using CCS PCM C Compiler, Version 4.007.
Ringo
_________________
Ringo Davis
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Sun Jul 22, 2007 10:35 am     Reply with quote

If I compile with CCS PCM C Compiler, Version 4.007 I get the funky problem I mentioned before. If I try to use 3.249 then I get out of ram errors. Is there a line I'm missing or something to make 3.249 work with ram better?

This is what 4.007 says
CCS PCM C Compiler, Version 4.007, 34836 22-Jul-07 12:16

Filename: F:\fw\Bartender\Bartender.lst

ROM used: 3105 words (38%)
Largest free fragment is 2048
RAM used: 154 (42%) at main() level
186 (51%) worst case
Stack: 6 worst case (1 in main + 5 for interrupts)


So it looks like I should have plenty. Why does 3.249 say I'm out of ram?

Here is my header stuff in case it helps.
#include <16F876a.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=19200, xmit=PIN_c6, rcv=PIN_c7)
#include <stdlib.h>


Thanks
Ringo
_________________
Ringo Davis
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jul 22, 2007 10:38 am     Reply with quote

Quote:
Is there a line I'm missing or something to make 3.249 work with ram better?

Add the items shown in bold below. The 2nd line enables use of all RAM
in the 16F-series PICs. (It's not needed for the 18F-series).
Quote:
#include <16F876a.h>
#device *=16
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=19200, xmit=PIN_c6, rcv=PIN_c7, ERRORS)
#include <stdlib.h>
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Sun Jul 22, 2007 10:47 am     Reply with quote

Thanks, That lets me compile with 3.249 but the code still does not execute. What am I missing?
Here is the C code and the code from the .lst file.

This code never executes
Code:

            value=1;
            while(value==0)             // 0 means still working, 1 means finished
            {
                output_low(PIN_B6);
                delay_ms(5000);             
                i2c_start();   // start condition
                i2c_write(BoardAddress + 1);
                value = i2c_read(0);
                i2c_stop();
                output_high(PIN_B6);
            }



Here is the corresponding lst code. It has been too long since I looked at assembly. Can anyone spot somethign wrong here?

.................... value=1;
0C20: MOVLW 01
0C21: MOVWF 5D
.................... while(value==0) // 0 means still working, 1 means finished
.................... {
0C22: MOVF 5D,F
0C23: BTFSS 03.2
0C24: GOTO 4A2
.................... output_low(PIN_B6);
0C25: BCF 06.6
0C26: BCF 03.5
0C27: BCF 06.6
.................... delay_ms(5000);
0C28: MOVLW 14
0C29: BSF 03.5
0C2A: MOVWF 5F
0C2B: BCF 03.5
0C2C: CLRF 28
0C2D: BTFSC 0B.7
0C2E: BSF 28.7
0C2F: BCF 0B.7
0C30: MOVLW FA
0C31: BSF 03.6
0C32: MOVWF 11
0C33: BCF 0A.3
0C34: BCF 03.6
0C35: CALL 3E0
0C36: BSF 0A.3
0C37: BTFSC 28.7
0C38: BSF 0B.7
0C39: BSF 03.5
0C3A: DECFSZ 5F,F
0C3B: GOTO 42B
.................... i2c_start(); // start condition
0C3C: BCF 03.5
0C3D: BSF 30.4
0C3E: MOVF 30,W
0C3F: BSF 03.5
0C40: MOVWF 07
0C41: MOVLW 04
0C42: MOVWF 77
0C43: DECFSZ 77,F
0C44: GOTO 443
0C45: BCF 03.5
0C46: BSF 30.3
0C47: MOVF 30,W
0C48: BSF 03.5
0C49: MOVWF 07
0C4A: MOVLW 03
0C4B: MOVWF 77
0C4C: DECFSZ 77,F
0C4D: GOTO 44C
0C4E: BCF 03.5
0C4F: BCF 07.4
0C50: BCF 30.4
0C51: MOVF 30,W
0C52: BSF 03.5
0C53: MOVWF 07
0C54: MOVLW 04
0C55: MOVWF 77
0C56: DECFSZ 77,F
0C57: GOTO 456
0C58: BCF 03.5
0C59: BCF 07.3
0C5A: BCF 30.3
0C5B: MOVF 30,W
0C5C: BSF 03.5
0C5D: MOVWF 07
.................... i2c_write(BoardAddress + 1);
0C5E: MOVLW 01
0C5F: ADDWF 5B,W
0C60: MOVWF 5F
0C61: BCF 03.5
0C62: CLRF 28
0C63: BTFSC 0B.7
0C64: BSF 28.7
0C65: BCF 0B.7
0C66: BSF 03.5
0C67: MOVF 5F,W
0C68: BCF 03.5
0C69: BSF 03.6
0C6A: MOVWF 11
0C6B: BCF 0A.3
0C6C: BCF 03.6
0C6D: CALL 3F4
0C6E: BSF 0A.3
0C6F: BTFSC 28.7
0C70: BSF 0B.7
.................... value = i2c_read(0);
0C71: CLRF 77
0C72: CLRF 28
0C73: BTFSC 0B.7
0C74: BSF 28.7
0C75: BCF 0B.7
0C76: BCF 0A.3
0C77: CALL 162
0C78: BSF 0A.3
0C79: BTFSC 28.7
0C7A: BSF 0B.7
0C7B: MOVF 78,W
0C7C: BSF 03.5
0C7D: MOVWF 5D
.................... i2c_stop();
0C7E: BCF 03.5
0C7F: BCF 30.4
0C80: MOVF 30,W
0C81: BSF 03.5
0C82: MOVWF 07
0C83: NOP
0C84: BCF 03.5
0C85: BSF 30.3
0C86: MOVF 30,W
0C87: BSF 03.5
0C88: MOVWF 07
0C89: BCF 03.5
0C8A: BTFSC 07.3
0C8B: GOTO 48E
0C8C: BSF 03.5
0C8D: GOTO 489
0C8E: MOVLW 04
0C8F: MOVWF 77
0C90: DECFSZ 77,F
0C91: GOTO 490
0C92: NOP
0C93: NOP
0C94: NOP
0C95: BSF 30.4
0C96: MOVF 30,W
0C97: BSF 03.5
0C98: MOVWF 07
0C99: MOVLW 04
0C9A: MOVWF 77
0C9B: DECFSZ 77,F
0C9C: GOTO 49B
.................... output_high(PIN_B6);
0C9D: BCF 06.6
0C9E: BCF 03.5
0C9F: BSF 06.6
.................... }
_________________
Ringo Davis
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Sun Jul 22, 2007 10:55 am     Reply with quote

I'm an idiot.

should be
value=0;
while(value==0)

DUHHHHHHH!
_________________
Ringo Davis
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