Newsgroup: italia.genova.discussioni
Titolo: Gratis per tutti ...

...buonanotte :-)
-- 
              ... Ciauz ...
         ... ActionMan ...©
 ... 
www.fastandclean.net
 ...

 ...buonanotte :-)
Bof. Siete tutti delle pippe.
-- 
Per ogni problema esiste sempre una soluzione semplice ed elegante.
E sbajata.

 
...ma quale misteriosa ragione ti tiene sempre alzato fino a quest'ora di
notte ?? ehhh ??? racconta...

 notte ?? ehhh ??? racconta...
/*********************************************
Project : 
Version : 
Date    : 20/01/2006
Author  : Guido Gambardella               
Company : TDD Tecnologie Digitali         
Comments: 
Chip type           : ATmega8
Program type        : Application
Clock frequency     : 4,000000 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 256
*********************************************/
#include <mega8.h>
#include <string.h>
//#include <stdlib.h>
#include <delay.h>
typedef unsigned char byte;
typedef unsigned int word;
#pragma regalloc-
#pragma optsize-
#define Debug     1
flash char Version[] = "$PTDD,PROD,NB,VER,1.0\r\n";
bit Bit0;
bit Bit1;
bit Bit2;
bit Bit3;
bit Bit4;
bit Bit5;
bit Bit6;
bit Bit7;
bit Bit8;
bit Bit9;
bit BitA;
bit BitB;
bit BitC;
bit BitD;
bit BitE;
bit BitF;
#define TxBusy    Bit0   // Set while transmitting.
#define T20Hz     Bit1   // set every 0,04992 seconds
#define Rx1Hard   Bit2   // if set stops soft UART Rx1
#define ErrOver   Bit3   // if set blinks the led 10 times per second
#define ErrTempl  Bit4   // if set blinks the led once a second
#define ForeAft   Bit2
#define PortStar  Bit3
#define Fore      Bit4
#define Port      Bit5
#define ADCchan   Bit2
//register byte @4 libero.
#define LedG      PORTD.5
#define LedR      PORTD.7
//#define Strobe1   PORTC.0
//#define Strobe2   PORTC.1
#define SW1       PINB.1
#define SW2       PINB.2
#define SW3       PINB.0
#define SW4       PINC.2
#define SW5       PINC.3
#define SW6       PINC.4
#define SW7       PINC.5
#define SW8       PIND.4
#define PortBset  0xCF
#define PortBdir  0xC0
#define PortCset  0x3C
#define PortCdir  0xC0
#define PortDset  0xFF
#define PortDdir  0xA2
#define Rx1In     0x01
#define Rx2In     0x04
#define Rx3In     0x08
#define Rx4In     0x40
byte SwitchChange(void){
static byte SwSet;
byte i;
  i = 0;
 
  if(SW1) i |= 1;
  if(SW2) i |= 2;
  if(SW3) i |= 4;
  if(SW4) i |= 8;
  if(SW5) i |= 16;
  if(SW6) i |= 32;
  if(SW7) i |= 64;
  if(SW8) i |= 128;
 
  if(i == SwSet) return(0);
  SwSet = i;
  return(1);
}
#include "intser.c"
#include "speedlog.c" 
#include "analog.c" 
#define Templates 16
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void){
  T20Hz = 1;   // 20,0320512820512820512820512820513 hetz.
  TCNT0 = 61;
}
struct tp{
  char id[5];
  byte chan;
  byte elapsed;
  byte filler;
};
struct tp TemplTable[Templates]; 
void ShowTempl(void){
byte i;
static byte curs;
  //if(TemplTable[curs].id[0] != 0){
 
  i=0;
  RxBuf[3,0]= curs + '0';
  RxBuf[3,1]= ' ';
  strncpy(RxBuf+(128*3)+2, TemplTable[curs].id, 5);
  RxBuf[3,7]= ' ';
  RxBuf[3,8]= TemplTable[curs].chan + '0';
  RxBuf[3,9]= ' ';
  RxBuf[3,10]= TemplTable[curs].elapsed + '0';
  RxBuf[3,11]='\r';
  RxBuf[2,12] = SynchChar;
  Putb(RxBuf+(128*3), 0);
  //}
  if(curs++ >= 8) curs=0;
}
// *************** MAIN ****************
void main(void) {
byte i, j;
byte chan;
char tt[5];
byte TimeOut;
byte templIx;
byte QueueCheck;
byte QueueOk;
// Input/Output Ports initialization
  PORTB = PortBset;
  DDRB = PortBdir;
  PORTC = PortCset;
  DDRC = PortCdir;
  PORTD = PortDset;
  DDRD = PortDdir;
// External Interrupts off
  MCUCR=0x00;
// Timer/Counter 0 clock 3,906 kHz
  TCCR0=0x05;
  TCNT0=61;
// Timer/Counter 1 Stopped
  TCCR1A=0x00;
  TCCR1B=0x00;
  TCNT1H=0x00;
  TCNT1L=0x00;
  ICR1H=0x00;
  ICR1L=0x00;
  OCR1AH=0x00;
  OCR1AL=0x00;
  OCR1BH=0x00;
  OCR1BL=0x00;
// Timer/Counter 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
  ASSR=0x00;
  TCCR2=0x00;
  TCNT2=0x00;
  OCR2=0x00;
// Analog Comparator: Off
  ACSR=0x80;
  SFIOR=0x00;
// Watchdog Timer Prescaler: OSC/2048k
  WDTCR=0x1F;
  WDTCR=0x0F;
 
  SwitchChange();
 
/*
SW1	SW2	Baud rate
OFF	OFF	4.800	 NMEA standard
OFF	ON	38.400	 NMEA fast (HS)
ON	OFF	9.600	
ON	ON	19.200	
*/
  UBRRH=0x00;   // USART Receiver: Off
  UCSRC=0x86;   // Set frame format: 8data, 2stop bit
  if(SW1){
    if(SW2) { UBRRL = 12; UCSRA = 0x40;}
    else {UBRRL = 26; UCSRA = 0x40;}
  }
  else {
    if(SW2) {UBRRL = 12; UCSRA = 0x42;}
    else {UBRRL = 51; UCSRA = 0x40;}
  }
  UCSRB=0x08;   // rx disable, Tx intr
  Rx1Hard = 0;
 
/*
SW3	SW4	Modalità
OFF	OFF	NMEA buffer
OFF	ON	Speedlog
ON	OFF	Analogico
ON	ON	Riservato
*/
  if(SW3){
    if(SW4) {#asm("rjmp __RESET");}
    else {Analog();}
  }
  else {
    if(SW4) {Speedlog();}
  }
 
/*
SW5 HS input
OFF	IN1 velocità 4.800 Baud.
ON	IN1 velocità uguale ad Out.
*/
  if(SW5){
    UCSRB=0x98;
    Rx1Hard = 1;
  }
 
/*
SW6 Messaggi doppi
OFF	Scarta i messaggi a priorità più bassa
ON	Ritrasmette anche i messaggi doppi
SW7, SW8 Timeout
OFF	OFF 30 sec.
OFF ON  30 sec.
ON  OFF 60 sec.
ON  ON  120 sec.
*/
 
  if(SW7){
    if(SW8) TimeOut = 150;
    else TimeOut = 75;
  }
  else {
    if(SW8) TimeOut = 38;
    else TimeOut = 38;//13;
  }
// Timer/Counter 2 500,000 kHz
// Mode: CTC top=OCR2
  ASSR=0x00;
  TCCR2=0x0A;
  TCNT2=0x00;
  OCR2=49;
// Timers Interrupts
  TIMSK=0x81;
	Rx1Check = '$' ^ '*';
	Rx2Check = '$' ^ '*';
	Rx3Check = '$' ^ '*';
	Rx4Check = '$' ^ '*';
  QueueCheck = 0;
  templIx = 0;
 
// Global enable interrupts
	#asm("sei")
 
	strcpyf(RxBuf, Version);
  Putb(RxBuf, 0);
 
// ************************* main loop No check *************************
  if(SW6){
    while(1){
      #asm("wdr");
 
     	if(T20Hz){
     	  T20Hz = 0;
        if(ErrOver) LedR = ~LedR;     // Fast blink
        if(SwitchChange())  #asm("rjmp __RESET");
      }
 
 	    if(QueueCount){
   	    if(QueueCount > (QueueLen-1)){
     	    ErrOver = 1;
   	      goto DeQueue1;
   	    }
        if(!Putb(&RxBuf[QueueBuf[QueueOut], 0], QueueRead[QueueOut])){
DeQueue1:
          QueueCount--;
       	  QueueOut++;
       	  QueueOut &= 0x0F;
        }
   	  }
	  }
  }
// ************************* main loop with check *************************
  while(1){
    #asm("wdr");
 
   	if(T20Hz){      // increment messages age
   	  T20Hz = 0;
 	    if(TemplTable[templIx].id[0] != 0){
     	  TemplTable[templIx].elapsed++;
     	  if(TemplTable[templIx].elapsed > TimeOut)
     	    TemplTable[templIx].id[0] = 0; // delete entry
     	}
      if(ErrOver) LedR = ~LedR;     // Fast blink
      templIx++;
      if(templIx == Templates){     // 1,25 times a second.
        templIx = 0; 
        if(ErrTempl) LedR = ~LedR;  // Slow blink
        if(SwitchChange())  #asm("rjmp __RESET");
//ShowTempl();
      }
    }
 
    if(QueueCount){    // Check message against template
      j = QueueRead[QueueCheck];
      chan = QueueBuf[QueueCheck];
 
      if(RxBuf[chan, j++] != '$') goto Discard; // Not a NMEA msg
      j &= (BufLen-1);
 
      for(i = 0; i < 5; i++){ // collect ID
        tt[i] = RxBuf[chan, j++];
        j &= (BufLen-1);
      }
 
      for(j = 0; j < Templates; j++){ // find same ID
        if(*tt == TemplTable[j].id[0]){
          if(strncmp(tt, TemplTable[j].id, 5) == 0){
            if(chan > TemplTable[j].chan){
Discard:      
              QueueBuf[QueueCheck] = 4;
              goto Done;
            }
            TemplTable[j].chan = chan;
            TemplTable[j].elapsed = 0;
            goto Done;
          }
        }
      }
 
      for(j = 0; j < Templates; j++){
        if(TemplTable[j].id[0] == 0){
          strncpy(TemplTable[j].id, tt, 5);
          TemplTable[j].chan = chan;
          TemplTable[j].elapsed = 0;
          break;
        }
      }
      if(j == Templates) ErrTempl = 1;
Done:
      QueueCount--;
      QueueCheck++;
      QueueCheck &= (QueueLen-1);
      QueueOk++;
    }
    if(QueueCheck != QueueOut){
      if(QueueBuf[QueueOut] > 3) goto DeQueue;
      if(Putb(&RxBuf[QueueBuf[QueueOut], 0], QueueRead[QueueOut])){
DeQueue:
         QueueOut++;
         QueueOut &= (QueueLen-1);
         QueueOk--;
   	  }
//   RxBuf[3,0]= QueueCount + '0';
//   RxBuf[3,1]= ' ';
//   RxBuf[3,2]= QueueOk + '0';
//   RxBuf[3,3]='\r';
//   RxBuf[3,4] = SynchChar;
//   while(Putb(RxBuf+(128*3), 0))
// 
	  }
 
    if((QueueCount >= QueueLen) || (QueueOk > (QueueLen-1))){
      ErrOver = 1;
      goto DeQueue;
    }
  }
}
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define TXC 6
#define RXC 7
#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)
#define TX_COMPLETE (1<<TXC)
#define BufLen    128
#define QueueLen  16
#define SynchChar 0x0A
char RxBuf[4, BufLen];
byte Rx1Write;
byte Rx2Write;
byte Rx3Write;
byte Rx4Write;
byte Rx1Start;
byte Rx2Start;
byte Rx3Start;
byte Rx4Start;
byte Rx1Check;
byte Rx2Check;
byte Rx3Check;
byte Rx4Check;
byte QueueRead[QueueLen];
byte QueueBuf[QueueLen];
byte QueueIn;
byte QueueOut;
byte QueueCount;
char* TxBuf;
byte TxRead;
register byte TxCount @4;
#define Rx1Cks    Bit8
#define Rx1Cks2   Bit9
#define Rx2Cks    BitA
#define Rx2Cks2   BitB
#define Rx3Cks    BitC
#define Rx3Cks2   BitD
#define Rx4Cks    BitE
#define Rx4Cks2   BitF
register byte RegGP   @5;
register byte RxBits  @6;
register byte Rx1Bit  @7;
register byte Rx1Byte @8;
register byte Rx2Bit  @9;
register byte Rx2Byte @10;
register byte Rx3Bit  @11;
register byte Rx3Byte @12;
register byte Rx4Bit  @13;
register byte Rx4Byte @14;
// Timer 2 output compare interrupt service routine
interrupt [TIM2_COMP] void timer2_comp_isr(void){
  RxBits = PIND;
 
  if(Rx1Hard) goto NoRx1;
 
LedR=0; 
	if(Rx1Bit == 0){		// idle?
		if((RxBits & Rx1In) == 0) Rx1Bit++; 		// start Rx
	}
	else {
		if(Rx1Bit & 1){	// sample input each other tick
			if(Rx1Bit < 18){		// data bit
#asm
			  LSR   R8
			  BST   R6, 0
			  BLD   R8, 7
#endasm
			}
			else{    // stop bit
				RxBuf[0, Rx1Write++] = Rx1Byte;
			 	Rx1Write &= (BufLen-1);	// wrap pointer
				if(Rx1Cks){
				  RegGP = Rx1Byte - '0';
				  if(RegGP > 9) RegGP -= 7;
#asm				  
				 LDS  R30,_Rx1Check
         SWAP R30
         STS  _Rx1Check,R30
#endasm         
				  if(RegGP == (Rx1Check & 0x0F)){
				    if(Rx1Cks2) Rx1Cks = 0;
				    else Rx1Cks2 = 1;
				  }
				}
				else{
				  Rx1Check ^= Rx1Byte;
				}
				if(Rx1Byte == '*') Rx1Cks = 1;
				if(Rx1Byte == SynchChar){
				  if(Rx1Cks == 0){
  				  QueueCount++;
  		      QueueRead[QueueIn] = Rx1Start;
  		      QueueBuf[QueueIn++] = 0;
  		      QueueIn &= (QueueLen-1);
  		    }
  		    Rx1Start = Rx1Write;
				  Rx1Check = '$' ^ '*';
				  Rx1Cks = 0;
				  Rx1Cks2 = 0;
		    }
				Rx1Bit = 0xFF;
			}
		}
		Rx1Bit++;
	} 
LedR=1; 
NoRx1:
	if(Rx2Bit == 0){		// idle?
		if((RxBits & Rx2In) == 0) Rx2Bit++; 		// start Rx
	}
	else {
		if(Rx2Bit & 1){	// sample input each other tick
			if(Rx2Bit < 19){		// data bit
#asm
			  LSR   R10
			  BST   R6, 2
			  BLD   R10, 7
#endasm
			}
			else{    // stop bit 
				RxBuf[1, Rx2Write++] = Rx2Byte;
			 	Rx2Write &= (BufLen-1);	// wrap pointer
				if(Rx2Cks){
				  RegGP = Rx2Byte - '0';
				  if(RegGP > 9) RegGP -= 7;
#asm				  
				 LDS  R30,_Rx2Check
         SWAP R30
         STS  _Rx2Check,R30
#endasm         
				  if(RegGP == (Rx2Check & 0x0F)){
				    if(Rx2Cks2) Rx2Cks = 0;
				    else Rx2Cks2 = 1;
				  }
				}
				else{
				  Rx2Check ^= Rx2Byte;
				}
				if(Rx2Byte == '*') Rx2Cks = 1;
				if(Rx2Byte == SynchChar){
				  if(Rx2Cks == 0){
  				  QueueCount++;
  		      QueueRead[QueueIn] = Rx2Start;
  		      QueueBuf[QueueIn++] = 1;
  		      QueueIn &= (QueueLen-1);
  		    }
  		    Rx2Start = Rx2Write;
				  Rx2Check = '$' ^ '*';
				  Rx2Cks = 0;
				  Rx2Cks2 = 0;
		    }
				Rx2Bit = 0xFF;
			}
		}
		Rx2Bit++;
	} 
	if(Rx3Bit == 0){		// idle?
		if((RxBits & Rx3In) == 0) Rx3Bit++; 		// start Rx
	}
	else {
		if(Rx3Bit & 1){	// sample input each other tick
			if(Rx3Bit < 19){		// data bit
#asm
			  LSR   R12
			  BST   R6, 3
			  BLD   R12, 7
#endasm
			}
			else{    // stop bit 
				RxBuf[2, Rx3Write++] = Rx3Byte;
			 	Rx3Write &= (BufLen-1);	// wrap pointer
				if(Rx3Cks){
				  RegGP = Rx3Byte - '0';
				  if(RegGP > 9) RegGP -= 7;
#asm				  
				 LDS  R30,_Rx3Check
         SWAP R30
         STS  _Rx3Check,R30
#endasm         
				  if(RegGP == (Rx3Check & 0x0F)){
				    if(Rx3Cks2) Rx3Cks = 0;
				    else Rx3Cks2 = 1;
				  }
				}
				else{
				  Rx3Check ^= Rx3Byte;
				}
				if(Rx3Byte == '*') Rx3Cks = 1;
				if(Rx3Byte == SynchChar){
				  if(Rx3Cks == 0){
  				  QueueCount++;
  		      QueueRead[QueueIn] = Rx3Start;
  		      QueueBuf[QueueIn++] = 2;
  		      QueueIn &= (QueueLen-1);
  		    }
  		    Rx3Start = Rx3Write;
				  Rx3Check = '$' ^ '*';
				  Rx3Cks = 0;
				  Rx3Cks2 = 0;
		    }
				Rx3Bit = 0xFF;
			}
		}
		Rx3Bit++;
	} 
	if(Rx4Bit == 0){		// idle?
		if((RxBits & Rx4In) == 0) Rx4Bit ++; 		// start Rx
	}
	else {
		if(Rx4Bit & 1){	// sample input each other tick
			if(Rx4Bit < 19){		// data bit
#asm
			  LSR   R14
			  BST   R6, 6
			  BLD   R14, 7
#endasm
			}
			else{    // stop bit 
				RxBuf[3, Rx4Write++] = Rx4Byte;
			 	Rx4Write &= (BufLen-1);	// wrap pointer
				if(Rx4Cks){
				  RegGP = Rx4Byte - '0';
				  if(RegGP > 9) RegGP -= 7;
#asm				  
				 LDS  R30,_Rx4Check
         SWAP R30
         STS  _Rx4Check,R30
#endasm         
				  if(RegGP ==  (Rx4Check & 0x0F)){
				    if(Rx4Cks2) Rx4Cks = 0;
				    else Rx4Cks2 = 1;
				  }
				}
				else{
				  Rx4Check ^= Rx4Byte;
				}
				if(Rx4Byte == '*') Rx4Cks = 1;
				if(Rx4Byte == SynchChar){
				  if(Rx4Cks == 0){
  				  QueueCount++;
  		      QueueRead[QueueIn] = Rx4Start;
  		      QueueBuf[QueueIn++] = 3;
  		      QueueIn &= (QueueLen-1);
  		    }
  		    Rx4Start = Rx4Write;
				  Rx4Check = '$' ^ '*';
				  Rx4Cks = 0;
				  Rx4Cks2 = 0;
		    }
				Rx4Bit = 0xFF;
			}
		}
		Rx4Bit++;
	} 
}
// USART Receiver interrupt service routine
interrupt [USART_RXC] void uart_rx_isr(void){
	Rx1Byte = UDR;
	if((UCSRA & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0){
		RxBuf[0, Rx1Write++] = Rx1Byte;
		Rx1Write &= (BufLen-1);	// wrap pointer
		if(Rx1Cks){
		  RegGP = Rx1Byte - '0';
		  if(RegGP > 9) RegGP -= 7;
#asm				  
      LDS  R30,_Rx1Check
      SWAP R30
      STS  _Rx1Check,R30
#endasm         
      if(RegGP ==  (Rx1Check & 0x0F)){
			  if(Rx1Cks2) Rx1Cks = 0;
			  else Rx1Cks2 = 1;
      }
    }
		else{
		  Rx1Check ^= Rx1Byte;
		}
		if(Rx1Byte == '*') Rx1Cks = 1;
		if(Rx1Byte == SynchChar){
		  if(Rx1Cks == 0){
			  QueueCount++;
	      QueueRead[QueueIn] = Rx1Start;
	      QueueBuf[QueueIn++] = 0;
	      QueueIn &= (QueueLen-1);
	    }
	    Rx1Start = Rx1Write;
		  Rx1Check = '$' ^ '*';
		  Rx1Cks = 0;
		  Rx1Cks2 = 0;
    }  	
	}
}
// USART Transmitter interrupt service routine
interrupt [USART_DRE] void uart_tx_isr(void){
   UDR = TxBuf[TxRead];
   TxCount++;
	 if((TxBuf[TxRead] == SynchChar) || (TxCount >= BufLen)){
     UCSRB.5 = 0;
	   LedG = 1;
	   TxCount = 0;
	 }
   TxRead++;
   TxRead &= (BufLen-1);
}
// Make sure that	TxBusy is 0 before calling!!!
byte Putb(char* buf, byte ix){
 
  if(LedG == 0) return 0;
 
  TxRead = ix;
  TxBuf = buf;
  while(UCSRA.UDRE == 0);
  UDR = TxBuf[TxRead];
  TxRead++;
  TxRead &= (BufLen-1);
	LedG = 0;
  UCSRB.5 = 1;
	return 1;
}
//appends to a null-terminated string the NMEA checksum and terminator
byte NMEAchecksum(char *sz){
byte ck;
	ck = '$';
	for(sz++; *sz > 0; sz++) 	ck ^= *sz;
 
	*sz++ = '*';
	*sz = ((ck >> 4) + '0');
	if(*sz > '9') *sz += 7;
	sz++;
	*sz = ((ck & 0x0F) + '0');
	if(*sz > '9') *sz += 7;
	sz++;
	*sz++ = '\r';
	*sz++ = '\n';
	*sz = '\0';
	return ck;
}
// always writes sign + 5 digits and nothing else
void itoa(int a, char *str){
char b[5];
byte i, j;
 
  i=0;
  if(a < 0) {*str++ = '-'; a = -a;}
  else *str++ = '+';
	do{ b[i++] = (a % 10 + '0'); } while((a /= 10) > 0);
	for(j=5; j>i; j--) *str++ = '0';
	while(i>0) *str++ = b[--i];
}
void bytetoa(byte a, char *str){
byte i;
 
	i = a / 100;
	*str++ = (i + '0');
	a -= (i*100);
	i = a / 10;
	*str++ = (i + '0');
	a -= (i*10);
	*str = (a + '0');
}
void Byte2Hex(byte i, char *str){
	*str = (((i >> 4) & 0x0F) + '0');
	if(*str > '9') *str += 7;
	str++;
	*str = ((i & 0x0F) + '0');
	if(*str > '9') *str += 7;
}
byte Hex2Byte(char *str){
byte b;
byte i;
	b = *(str++) - '0';
	if(b > '9') b-= 7;
	if(b > 80) b-= 32;
	i = b << 4;
	b = *(str++) - '0';
	if(b > '9') b-= 7;
	if(b > 80) b-= 32;
	i += b;
	return i;
}
flash char LogMsg[] = "$VDVBW,+00.0,+00.0,A,+00.0,+00.0,V";
#define Tim2ext1 Rx1Byte
#define Tim2ext2 Rx1Bit
#define Tim1ext2 Rx2Byte
word MinPulse;
union u {
  byte b[4];
  word w[2];
  unsigned long l;
};
union u Read1;
union u Read2;
// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void){
 
  Read1.b[0] = TCNT1L;
  Read1.b[1] = TCNT1H;
  Read1.b[2] = Tim1ext2;
  Fore = PIND.0;
  if(Read1.l > MinPulse){
    TCNT1H = 0;
    TCNT1L = 0;
    Tim1ext2 = 0;
    ForeAft = 1;
  }
}
// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void){
  Read2.b[0] = TCNT2;
  Read2.b[1] = Tim2ext1;
  Read2.b[2] = Tim2ext2;
  Port = PIND.6;
  if(Read2.l > MinPulse){
    TCNT2 = 0;
    Tim2ext1 = 0;
    Tim2ext2 = 0;
    PortStar = 1;
  }
}
interrupt [TIM1_OVF] void timer1_ovf_isr(void){
  Tim1ext2++;
}
// Timer 2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void){
  Tim2ext1++;
  if(Tim2ext1 == 0) Tim2ext2++;
}
void WriteNum(char* s, byte minus, word a){
int i;
 
  if(minus) *s = '-';
  *s++;
  i = a / 100;
  *s++ = i + '0';
  a -= i * 100;
 
  i = a / 10;
  *s++ = i + '0';
  a -= i * 10;
 
  s++;
  *s++ = a + '0';
}
void Speedlog(void){
byte time; 
byte secA;
byte secB;
byte secC;
byte lonSign;
byte traSign;
word lon, tra;
long timeconst;
long l;
// Timer1 Clock 62500 Hz
// Overflow Interrupt
 TCCR1A=0x00;
 TCCR1B=0x03;
 TCNT1H=0x00;
 TCNT1L=0x00;
 ICR1H=0x00;
 ICR1L=0x00;
 OCR1AH=0x00;
 OCR1AL=0x00;
 OCR1BH=0x00;
 OCR1BL=0x00;
// Timer2 Clock 62500 Hz
// Overflow Interrupt
 ASSR=0x00;
 TCCR2=0x04;
 TCNT2=0x00;
 OCR2=0x00;
  TIMSK=0x45; // all timers overflows on
  GICR=0xC0;  // both extint on
  MCUCR=0x0A;
  GIFR=0xC0;
/*
SW5 e SW6 Tipo di solcometro
SW5	SW6	Tipo di solcometro
OFF	OFF	Doppler velocità acqua
OFF	ON	Doppler velocità terra
ON	OFF	Elettromagnetico
ON	ON	Meccanico
VD Velocity Sensor, Doppler, other/general
DM Velocity Sensor, Speed Log, Water, Magnetic
VW Velocity Sensor, Speed Log, Water, Mechanical
$--VBW,x.x,x.x,A,x.x,x.x,A*hh
1) Longitudinal water speed, "-" means astern
2) Transverse water speed, "-" means port
3) Status, A = data valid
4) Longitudinal ground speed, "-" means astern
5) Transverse ground speed, "-" means port
6) Status, A = data valid
*/
  strcpyf(RxBuf+128, LogMsg);
 
  if(SW5){
    if(SW6) {RxBuf[1,1] = 'D'; RxBuf[1,2] = 'M';}   // Magnetic
    else {RxBuf[1,2] = 'W';}                        // Mechanical
  }
  else{
    if(SW6){              // ground speed
      RxBuf[1, 17] = 'V';
      RxBuf[1, 29] = 'A';
    }
  }
 
/*
SW7 SW8 Impulsi
OFF	OFF 200 impulsi per miglio
OFF ON	2000 impulsi per miglio
ON	OFF 100 impulsi per miglio
ON	ON	1000 impulsi per miglio
*/
  if(SW7){
    if(SW8){
      timeconst = 225000000;
      MinPulse = 22501;
    }
    else{
      timeconst = 22500000;
      MinPulse = 2251;
   }
  }
  else{
    if(SW8){
      timeconst = 112500000;
      MinPulse = 11251;
    }
    else{
      timeconst = 11250000;
      MinPulse = 1126;
    }
  }
 
  lon = 0;
  tra = 0;
  time = 0;
  secA = 0;
  secB = 0;
  secC = 0;
 
// Global enable interrupts
	#asm("sei")
 
	strcpyf(RxBuf, Version);
  Putb(RxBuf, 0);
 
  while(1){
   	#asm("wdr")
    if(T20Hz){
   	  T20Hz = 0;
      time++;
      if(time > 19){
        time = 0;
        secA++;
        secB++;
        secC++;
        if(SwitchChange())  #asm("rjmp __RESET");
      }
 
#ifdef Debug
      if(secA > 0){
#else
      if(secA > 30){
#endif
        secA = 0;
        strcpy(RxBuf, RxBuf+128);
        WriteNum(RxBuf+ 7, lonSign, lon);
        WriteNum(RxBuf+13, traSign, tra);
        WriteNum(RxBuf+21, lonSign, lon);
        WriteNum(RxBuf+27, traSign, tra);
        NMEAchecksum(RxBuf);
        Putb(RxBuf, 0);
      }
      if(secB > 180){
        lon = 0;
  	    secB = 0;
      }
      if(secC > 180){
        tra = 0;
  	    secB = 0;
      }
    }
 
    if(ForeAft){
    	#asm("cli")
    	l = Read1.l;
    	lonSign = ~Fore;
    	ForeAft = 0;
	    #asm("sei")
      if(l > timeconst){
        lon = 0;
      }
      else{
        l = timeconst / l;
        lon = l;
        secB = 0;
      }
     }
    if(PortStar){
    	#asm("cli")
    	l = Read2.l;
    	traSign = ~Port;
    	PortStar = 0;
	    #asm("sei")
      if(l > timeconst){
        tra = 0;
      }
      else{
        l = timeconst / l;
        tra = l;
        secC = 0;
      }
    }
  }
} 
#define ADCset 0x8D;  //ADC single, intr, prescale 32 = 8928 Samp/sec =
89,28 samp/semionda
flash char RudMsg[] = "$YXRSA,+00.0,A,+00.0,V";
flash char EngMsg[] = "$ERRPM,S,1,000.0,+00.0,A";
eeprom int Cal[2,3];
word Res;
// ADC interrupt service routine
interrupt [ADC_INT] void adc_isr(void){
  Res += ADCW;
}
// Read the AD conversion result
// with noise canceling
word ReadADC(byte chan){
byte i;
word res;
 
  ADMUX = 0x40 + chan;
  Res = 0;
  for(i = 0; i < 64; i++){
    ADCSRA = ADCset;
#asm
    in   r30,mcucr
    cbr  r30,__sm_mask
    sbr  r30,__se_bit | __sm_adc_noise_red
    out  mcucr,r30
    sleep
    cbr  r30,__se_bit
    out  mcucr,r30
#endasm
  }
  res = Res >> 3; 
  if((Res & 63) > 32) res++;
  return res;
}
Analog(void){
word cal[2, 3];
word res[2];
byte i;
byte state;
byte time;
byte secA;
  TIMSK=0x01;
/*
SW5 e SW6 Tipo di sensore
SW5	SW6	Tipo di sensore
OFF	OFF	Angolo di barra 1 timone
OFF	ON	Angolo di barra 2 timoni
ON	OFF	Giri motore
ON	ON	Giri motore 2 assi
$YXRSA,x.x,A,x.x,A*hh
1) Starboard (or single) rudder sensor, "-" means Turn To Port
2) Status, A means data is valid
3) Port rudder sensor
4) Status, A means data is valid
$ERRPM,a,x,x.x,x.x,A*hh
1) Source; S = Shaft, E = Engine
2) Engine or shaft number
3) Speed, Revolutions per minute
4) Propeller pitch, % of maximum, "-" means astern
5) Status, A means data is valid
*/
 
  if(SW5){
    strcpyf(RxBuf+128, EngMsg);
  }
  else{
    strcpyf(RxBuf+128, RudMsg);
    if(SW6) RxBuf[1,21] = 'A';
  }
 
  state = 0;
  time = 0;
  secA = 0;
  for(i = 0; i < 3; i++){
    cal[0,i] = Cal[0,i];
    cal[1,i] = Cal[1,i];
  }
 
// Global enable interrupts
	#asm("sei")
 
	strcpyf(RxBuf, Version);
  Putb(RxBuf, 0);
  while(1){
   	#asm("wdr")
/*
SW7 Setup
OFF	Normal operation
ON	Calibrate
SW8 Calibrate
OFF	changing
ON	reading
*/
    if(SW7){    // setup mode
      switch(state){
      case 0:
        LedR = 0;
        delay_ms(1000);
        state++;
        break;
      case 1:
      case 5:
        if(SW8){
          LedG = 0;
          delay_ms(300);
          state++;
        }
        break;
      case 3:
      case 7:
        if(SW8 == 0){
          LedG = 0;
          delay_ms(300);
          state++;
        }
        break;
      case 2:
      case 4:
      case 6:
        cal[0, (state/2)-1] = ReadADC(0);
        cal[1, (state/2)-1] = ReadADC(1);
        LedG = 1;
        delay_ms(300);
        state++;
        break;
      case 8:
        for(i = 0; i < 3; i++){
          cal[0,i] = Cal[0,i];
          cal[1,i] = Cal[1,i];
        }
        state++;
        LedR = 1;
        LedG = 1;
        break;
      }
    }
    else{       // normal operation
      if(state > 0) #asm("rjmp __RESET");
 
      if(T20Hz){
     	  T20Hz = 0;
        time++;
        if(time > 19){
          time = 0;
          secA++;
        }
      }
 
      if(secA > 0){
        secA = 0;
        if(SW6) ADCchan = ~ADCchan;
        strcpy(RxBuf, RxBuf+128);
        //WriteNum(RxBuf+7,  0, res[0]);
        //WriteNum(RxBuf+7,  0, Res);
        //if(SW6) WriteNum(RxBuf+15, 0, res[1]);
        itoa(ReadADC(1) - cal[1,0], RxBuf+7);
        itoa(ReadADC(0) - cal[0,0], RxBuf+15);
        //itoa(cal[1,1], RxBuf+7);
        //itoa(cal[0,1], RxBuf+15);
        NMEAchecksum(RxBuf);
        Putb(RxBuf, 0);
      }
    }
  }
}
L'hardware, invece, è uscito buono alla prima.


 L'hardware, invece, è uscito buono alla prima.
...perfetto !!!  Adesso cambio i commentari e lo rivendo !!!  
grassie.... :-))))

 ...perfetto !!!  Adesso cambio i commentari e lo rivendo !!!  
Però prima devi capire a che serve e come disegnare un hardware
compatibile. Per un esperto programmatore come te sarà un giochetto...


 compatibile. 
E'un programma per far funzionare l'incursore anale?

 
Non sono un hardware-man. Non lo sono mai stato...<sigh>....
Se no sarei miliardario....

 E'un programma per far funzionare l'incursore anale?
Ste, la vicinanza col Bertolazzi a te ti fa male ...
Lena e Susanna saranno deluse... :-))

Ste:

LOL!
Già, a proposito, mi serve un collaudatore...


 Già, a proposito, mi serve un collaudatore...
IO IO IOOOOOO PRRRRRRRRRRRIIIIIIIIIIIIIIIIIMOOOOOOOOOOOOOOOOOOOOOOO TANA PER
MAX!!!
:D
-- 
Baxi, Max
"Mio nonno guidava l'autobus e le corriere di linea, ed io spero sempre
di morire come lui, tranquillamente nel sonno, non urlando come i suoi
passeggeri..."
http://www.tappullo.com

 TANA PER MAX!!!
Tana... Beh, più che tana, viste le dimensioni dovute ad anni di abusi,
quella di Max la definirei grotta. Non vai bene. L'incursore si metterebbe
a rimbalzare da un lato all'altro con effetti imprevedibili. Troppo
pericoliso.
Se aveva ragione Freud con la sua teoria del carattere anale (stretto in
tutto, caga e spende il minimo indispensabile), ci vorrebbe, chessò, un
Rotta od un LG.


 pericoliso.
Insomma, come buttare un salame in un corridoio.

Insomma, come buttare un salame in un corridoio.
 UAAAOOOAAA!

Alessandro Topo Galileo:

Come fai a saperlo? (ROTFL)
