



#include <16F690.h>
#fuses xt,NOWDT,NOPROTECT,MCLR
#use delay(clock=3579545)



#use rs232(baud=1200, float_high, bits=9, xmit=PIN_A2, rcv=PIN_A2)

#include "flex_lcd16x1.h"

#define OUR_ID 1

#define MAX_MESSAGES 4
#define MAX_LENGTH   7
#define INTS_PER_SECOND 50
#define SAMPLET	5


int1 d_clr;
byte pbus_buffer[MAX_MESSAGES][MAX_LENGTH+1];
byte next_in=0;
byte next_out=0;
enum pbus_states {PBUS_IDLE=0x80,PBUS_NEED_LEN=0x81,PBUS_NEED_TO=0x82,
                  PBUS_NEED_FROM=0x83,PBUS_NEED_CS=0x84};
byte pbus_state=PBUS_IDLE;
byte checksum;
byte last_byte;
byte data;
byte to,len,msg[MAX_LENGTH];
long int_count, sampleb;
int ori, dest;
int m_r, resp;

#bit ninth_bit = RS232_ERRORS.7
#bit collision = RS232_ERRORS.6
#bit intf = 11.1

//-------------------------------------------------------------------------------------

#int_TIMER0                        // This function is called every time
void clock_isr() 
{                 					// the RTCC (timer0) overflows (255->0).
    set_timer0(116);                // For this program this is apx 139 times

	 if(--int_count==0) 			// per second.
	{           
      int_count=INTS_PER_SECOND;

	  if (sampleb)
	  {
	  	sampleb--;
	  	if(!sampleb)
	  	{
	  		d_clr=1;
	  		ori=0;
	  		dest=0;
	  		msg[0]=0;
	  		resp=0;
	  		m_r =0;

	  	}
	  }
    }
}    

//-------------------------------------------------------------------------------------



#int_ext
void pbus_isr() {


    if(kbhit()) {

      data=getc();

      if(ninth_bit) {
         switch(pbus_state) {
           case PBUS_IDLE : if(data==0xf1)
                                pbus_state=PBUS_NEED_TO;
                            break;
           case PBUS_NEED_TO :
                            if(data==OUR_ID)
                               pbus_state=PBUS_NEED_FROM;
                            else
                               pbus_state=PBUS_IDLE;
                            checksum=data;
                            
                            break;
           case PBUS_NEED_FROM :
                            pbus_buffer[next_in][0] = data;
                            pbus_state=PBUS_NEED_LEN;
                            checksum^=data;
                            break;
           case PBUS_NEED_LEN :
                            last_byte = data+1;
                            pbus_buffer[next_in][1] = data;
                            pbus_state=2;
                            checksum^=data;
                            break;
         }
      } else
        if(pbus_state==PBUS_NEED_CS) {
           if(checksum==data)
               next_in = (next_in+1) % MAX_MESSAGES;
           pbus_state=PBUS_IDLE;
        } else if(pbus_state<0x80) {
           pbus_buffer[next_in][pbus_state] = data;
           checksum^=data;
           if(++pbus_state>last_byte)
              pbus_state=PBUS_NEED_CS;
      }
    }
}


//-------------------------------------------------------------------------------------



void pbus_send( byte * message, byte to, byte len) {
   byte checksum,i;

   retry:
      checksum=len^OUR_ID^to;
      disable_interrupts(GLOBAL);
      collision=false;
      ninth_bit=1;

      putc(0xf1);           if(collision) goto error;
      putc(to);             if(collision) goto error;
      putc(OUR_ID);         if(collision) goto error;
      putc(len);            if(collision) goto error;
      ninth_bit=0;
      for(i=1;i<=len;++i) 
	  {
        checksum^=*message;
        putc(*(message++)); if(collision) goto error;
      }
      putc(checksum);       if(collision) goto error;
      intf=false;
      enable_interrupts(GLOBAL);
      return;

   error:
      delay_ms(16);
      enable_interrupts(GLOBAL);
      goto retry;
}




//-------------------------------------------------------------------------------------



#include <input.c>

#zero_ram
void main() {
   byte to,len,i,msg[MAX_LENGTH];
	
	setup_timer_0 (RTCC_DIV_128 | RTCC_INTERNAL);
 	set_timer0(116);
 	int_count=INTS_PER_SECOND;
   lcd_init();
   lcd_putc("Proyecto Com3");
	delay_ms(250);

   ext_int_edge( h_to_l );
   enable_interrupts(INT_TIMER0);
   enable_interrupts(int_ext);
   enable_interrupts(global);
   len=1;

   do {
      if(next_in!=next_out) 
	  {
         ori=pbus_buffer[next_out][0];
         dest=pbus_buffer[next_out][2];
         to=dest; 
         if(resp==dest&&m_r==1) m_r =2; 
         next_out=(next_out+1) % MAX_MESSAGES;
         if(m_r==2)
	     {
	         sampleb=SAMPLET;
	         msg[0]=ori;		 
	         printf(lcd_putc,"%d->",ori);
	         printf(lcd_putc,"%d ",dest);
	         pbus_send(msg,to,len);
         }
         if(!m_r)
         {
	         resp=ori;
	         msg[0]=ori;
	         m_r=1;
	         pbus_send(msg,to,len);
	         printf(lcd_putc,"\f%d->",ori);
	         printf(lcd_putc,"%d ",dest);
         }

      }

		if (d_clr) 
	      {	
	      	printf(lcd_putc,"\fProyecto Com3");
	      	d_clr=0;
	      }	

   } while (TRUE);
}
