PrinceNai
 
 
  Joined: 31 Oct 2016 Posts: 554 Location: Montenegro 
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				| i2c sniffer | 
			 
			
				 Posted: Thu Mar 21, 2019 1:37 pm     | 
				     | 
			 
			
				
  | 
			 
			
				Dear All,
 
 
This is an I2C sniffer using 18f4520. It is very basic, doesn't handle restart conditions (or maybe it does, the communication I'm listening to doesn't use them). The extracted data is stored in the buffer. No parsing is done. 
 
 
main.h
 
 
 	  | Code: | 	 		  
 
#include <18F4520.h>
 
#device ADC=10
 
 
#FUSES NOWDT                    //No Watch Dog Timer
 
 
#device ICD=TRUE
 
#use delay(internal=32000000)
 
#use i2c(Slave,Fast,sda=PIN_C4,scl=PIN_C3,force_hw,address=0x0)  
 
 | 	  
 
 
main.c
 
 	  | Code: | 	 		  
 
#include <main.h>
 
#INCLUDE <ctype.h>
 
#BYTE SSPCON1 = 0XFC6 
 
#BYTE SSPSTAT = 0XFC7 
 
 
 
#define S SSPSTAT, 3
 
#define P SSPSTAT, 4 
 
#define SCL PIN_C3 
 
#define SDA PIN_C4 
 
 
char test;  
 
int8 COLLECT = 0;
 
#define WAIT_CLK 2                             
 
#define IDLE 0                                                                      
 
#define SAMPLE_DATA 1                                                                                               
 
#define WAIT_ACK 3
 
int8 Sample_Counter = 0;
 
int8 Raw_Data = 0;         
 
                          
 
#define BUFFER_SIZE 200                       //create 200 byte large buffer
 
char buffer[BUFFER_SIZE]; 
 
int8 next_in = 0;                                              
 
int1 Store = 0;
 
 
//-----------------------------------------------------------------------------
 
//----------------------------- clear buffer ----------------------------------
 
void Clear_UART_Buffer() {          
 
   next_in=0;                                                                                 
 
   while (next_in < BUFFER_SIZE){                                                                   
 
      buffer[next_in] = '\0';                      
 
      next_in++;
 
   }
 
   next_in=0;
 
}
 
 
 
// ****************************************************************************
 
#INT_EXT                         
 
void  EXT_isr(void) {                          
 
                                                  
 
}                            
 
                                            
 
                                                                                                       
 
#INT_SSP                                                        
 
void  SSP_isr(void) {
 
   Sample_Counter = 0; 
 
}                         
 
                      
 
 
// ****************************************************************************
 
                                                                                   
 
void main() {
 
   bit_set(SSPCON1,3);              // enable SSP interrupt on START and STOP
 
//   enable_interrupts(INT_EXT);
 
   enable_interrupts(INT_SSP);                                              
 
   enable_interrupts(GLOBAL);
 
   output_high(PIN_B5);
 
   
 
   Clear_UART_Buffer();
 
                                                                                    
 
   
 
   while(TRUE){                           
 
      while(bit_test(S)){           // START was the last thing seen on the line 
 
      test = input_c();             
 
      delay_cycles(1);              // have start?                  
 
 
                                      
 
         switch (COLLECT){        
 
         
 
// .-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.        
 
// As soon as we se a STOP condition or we sample the data, SCK line is still high. 
 
// Here we wait for SCK to go low after START condition or after sampling
 
// .-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.       
 
            case IDLE:{         
 
               if(Store){                                 
 
                  Store = 0;                 // move received character to buffer
 
                  if(isalpha(Raw_Data)){
 
                     buffer[next_in] = Raw_Data;             
 
                     next_in++;
 
                     if(next_in > BUFFER_SIZE){                                    
 
                        next_in = 0;                                   
 
                     }               
 
                  }                                                                     
 
                                                                      
 
                  
 
               }             
 
               while(input_state(SCL)){      // wait till PIN_C3 (SCK) goes low            
 
               }
 
               COLLECT = WAIT_CLK; 
 
               break;                                                                             
 
            }                                                                                       
 
          
 
// .-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
 
// The second state is waiting while the SCK is low for the next transition             
 
// to high, where we sample the data. When we detect a change on SCK from 
 
// LOW to HIGH, we sample SDA.
 
// .-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.         
 
            case WAIT_CLK:{                  // and back high
 
               while(!input_state(SCL)){     // wait till PIN_C3 (SCK) goes high                  
 
               } 
 
               if(Sample_Counter == 8){
 
                  Sample_Counter = 0;                                    
 
                  COLLECT = WAIT_ACK;                               
 
                  break;                  
 
               }             
 
                                                                       
 
               COLLECT = SAMPLE_DATA;                               
 
               break;                                        
 
            }                                                        
 
                   
 
// .-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.                 
 
// Here we actually sample the data (SCK HIGH, SDA stable)
 
// .-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.           
 
            case SAMPLE_DATA:{               // SCK high to low, then low to high. Data is valid then.
 
               output_low(PIN_B5);           // get some visual indication that something is going on
 
                                                                                                                                   
 
               if(input_state(SDA)){                                                        
 
                  bit_set(Raw_Data,0);                                                  
 
               }                                                                                                
 
               else{                                  
 
                  bit_clear(Raw_Data,0);
 
               }
 
               
 
               if(Sample_Counter < 7){       // rotate until 7 bits of data are extracted
 
                  rotate_left(&Raw_Data,1);                                                     
 
               }
 
                                             // don't rotate last bit                                             
 
               if(Sample_Counter == 7){      // got all 8 bits, move data to buffer
 
                  Store = 1;
 
               }
 
               
 
               Sample_Counter++;                                                                                                                          
 
               output_high(PIN_B5);
 
               COLLECT = IDLE; 
 
               break;                                          
 
            }                                 
 
   
 
// .-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
 
            case WAIT_ACK:{
 
               COLLECT = IDLE;                                 
 
               break;                                                
 
            }
 
// .-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-                                                   
 
         }   //switch                                                                                             
 
                                                                   
 
      }     // while S                                                         
 
 
                                                                                          
 
 
 
 
 
   while(bit_test(P)){              // sit here, STOP was the last thing seen  
 
   }
 
                                                         
 
     delay_cycles(1);                                                 
 
   }                                                                    
 
                                                          
 
}                                                                
 
 | 	 
  | 
			 
		  |