

//------------------------------------------------------------------------------------
// main_project_mega8_Jonson.cpp
//------------------------------------------------------------------------------------
// Copyright 2004 - 2007 biCOMM , Inc.
//
// AUTH: Valeri Tosev
// DATE: 2008
//
// Target: ATmega8
//
// Tool chain: IAR Embedded Workbench 4.30
//             

//------------------------------------------------------------------------------------
// Includes and defines
//------------------------------------------------------------------------------------
#include <stdio.h>
#include <stdbool.h>
#include "iom8.h"
#include "delay.h"
#include "def_Atmega8_28DIL.h"

#define BIT(x)  (1<<(x))
//------------------------------------------------------------------------------------
// Macro definitions
//------------------------------------------------------------------------------------
#define sbi(port,bit)  (port |= (1<<bit))   //set bit in port
#define cbi(port,bit)  (port &= ~(1<<bit))  //clear bit in port
#define test_bit(port,x) (port&BIT(x)) //Test bit x of port

//------------------------------------------------------------------------------------
// Definitions for constants
//------------------------------------------------------------------------------------

#define     F_clk      16000000 //Sys clock


unsigned char tempUDR;
int CounterTimer0;
unsigned char flagCompare;
unsigned int N;  // constanta prescaler
unsigned char Corrector;  // constanta corrector
unsigned char k;
unsigned long int X;
unsigned long int X1;
unsigned long int X2;
unsigned long int B;
unsigned long int freq;
unsigned long int VarTCNT1;
unsigned char bufUART[255];
bool flagBufFull;
unsigned int i;
unsigned long int Temp;
char bcd_code;


void USART_init()
{
  // 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
UCSRA=0x02;
UCSRB=0x98;

// USART Baud rate: 9600 для 1 MHz 
UBRRH=0x00;
UBRRH=0x86;
//UCSRC=0x86;
  UBRRL=207;  // USART Baud rate: 9600 for 16 MHz 
 //UBRRL=12;  // USART Baud rate: 9600 for 1 MHz 
  
}

void USART_Transmit( char data1)
{
/* Wait for empty transmit buffer */
  while ( !( UCSRA & (1<<UDRE)) ) 
            {    };

/* Put data into buffer, sends the data */
//data1=~data1;
UDR = data1;

}


void USART_Resive( )
{
  char data3;
/* Wait for empty transmit buffer */
 while ( !(UCSRA & (1<<RXC)) )
   
    {     };

/* Get and return received data from buffer */
 data3=UDR;
 USART_Transmit( data3);
}

void Timer0_init( )
{
 sbi(TCCR0,CS01);            // TCCR0  =  (1 << CS01) ;
 TCNT0=0x7c;                 // Sys Timer = 1ms
 //sbi(TIMSK,TOIE0);         //TIMSK0   |= (1 << TOIE0);
 
}

void Timer1_init( )
{
  
 //TIMER1 initialize - Fast PWM mode
 // TCCR1B = 0x00; //stop Timer

 // WGM: 15) 
 //sbi(TCCR1A,WGM10);
// sbi(TCCR1A,WGM11);
// sbi(TCCR1B,WGM12);
// sbi(TCCR1B,WGM13); 
 
 // sbi(TCCR1A,COM1A1);
 // cbi(TCCR1A,COM1A0);
  
 // OCR1A=0x001f;
 // TCNT1H=0;
 // TCNT1L=0;
  
  
 //Timer1 initialize -CTC mode
  
  TCCR1B = 0x00; //stop Timer
  cbi(TCCR1A,WGM10);
  cbi(TCCR1A,WGM11);
  
  cbi(TCCR1A,COM1A1);
  sbi(TCCR1A,COM1A0);
 
 // cbi(TCCR1A,COM1B1);
 // sbi(TCCR1A,COM1B0);
  
  sbi(TCCR1B,WGM12);
  cbi(TCCR1B,WGM13);
 
 
  flagCompare=0;
  OCR1A=0xfff0;
  TCNT1H=0x0;
  TCNT1L=0x0;
 
}
void Timer2_init( )
{
  
 //TIMER2
//Register TCCR2 - Timer Counter Control Register 2
//7 FOC - Force output compare - NU in PWM
//6,3 WFG - WaveFormGenerator mode - 11 Fast PWM
//5:4 COM - Compare Match Output mode - 10 clear OC2 jn compare match, set OC2 at BOTTOM - non-inverting mode
//2:0 CS - Clock Select - 001 Clk/1
 
  
  
  TCCR2 = 0x00; //stop Timer
  sbi(TCCR2,WGM20);//6,3 WFG - WaveFormGenerator mode - 11 Fast PWM
  sbi(TCCR2,WGM21);
  
  sbi(TCCR2,COM21);//5:4 COM - Compare Match Output mode - 10 clear 
  sbi(TCCR2,COM20);//OC2 jn compare match, set OC2 at BOTTOM - non-inverting mode
 
  sbi(TCCR2,CS20);//2:0 CS - Clock Select - 001 Clk/1
  sbi(TCCR2,CS21);//2:0 CS - Clock Select - 001 Clk/1
  sbi(TCCR2,CS22);//2:0 CS - Clock Select - 001 Clk/1
  
  OCR2=127; //set Output Compare Register 2
  
  sbi(TIMSK,TOIE2);
  
 
}
////////////////////////////////////////////////
 // This subroutine calculate parameters for TIMER1 - mode CTC for generate
 // pulces with frequency 1 - 2200 Hz
 //
 //////////////////////////////////////////////////

void CalcParameterTimer1CTC_Mode(unsigned long int freq,unsigned long int B)
{
 
 
  
  if ((freq>=250)&&(freq<=2200))
  {
      //  sbi(TCCR1B,CS10);  //start Timer - clkI/O/1 (No prescaling)
      //  cbi(TCCR1B,CS11);
     //   cbi(TCCR1B,CS12);
        N=1;
       Corrector=34;
  }
  
    
  if((freq>=35)&&(freq<=249))
     {         //       cbi(TCCR1B,CS10);  //start Timer - clkI/O/8 (From prescaler)
               //       sbi(TCCR1B,CS11);
               //       cbi(TCCR1B,CS12);
                      N=8;
                      Corrector=8;
                  }
  if((freq>=11)&&(freq<=34))
                    { //sbi(TCCR1B,CS10);  //start Timer - clkI/O/64 (From prescaler)
                     //sbi(TCCR1B,CS11);
                     //cbi(TCCR1B,CS12);
                      N=64;
                     // Corrector=8;
  }
  if((freq>=1)&&(freq<=10))
                    { //cbi(TCCR1B,CS10);  //start Timer - clkI/O/256 (From prescaler)
                     //cbi(TCCR1B,CS11);
                     //sbi(TCCR1B,CS12);
                      N=256;
                     // Corrector=8;
  }
  X=(F_clk/(freq*N)) ;
  X1=X*B;
  X1=X1/100;
  X2=X-X1;
  VarTCNT1=65535-X2+ Corrector;
  OCR1A=X1;
   if ((freq>=250)&&(freq<=2200))
  {
        sbi(TCCR1B,CS10);  //start Timer - clkI/O/1 (No prescaling)
        cbi(TCCR1B,CS11);
        cbi(TCCR1B,CS12);
       // N=1;
       // Corrector=34;
  }
  
    
  if((freq>=35)&&(freq<=249))
     {               cbi(TCCR1B,CS10);  //start Timer - clkI/O/8 (From prescaler)
                     sbi(TCCR1B,CS11);
                     cbi(TCCR1B,CS12);
                  //    N=8;
                  //    Corrector=8;
                  }
  if((freq>=11)&&(freq<=34))
                    {  sbi(TCCR1B,CS10);  //start Timer - clkI/O/64 (From prescaler)
                       sbi(TCCR1B,CS11);
                       cbi(TCCR1B,CS12);
                     // N=64;
                     // Corrector=8;
  }
  if((freq>=1)&&(freq<=10))
                    {  cbi(TCCR1B,CS10);  //start Timer - clkI/O/256 (From prescaler)
                       cbi(TCCR1B,CS11);
                       sbi(TCCR1B,CS12);
                     // N=256;
                     // Corrector=8;
  }
  
}



char CHAR2BCD2(char input)
{
    char high = 0;
    
    
    while (input >= 10)                 // Count tens
    {
        high++;
        input -= 10;
    }

    return  (high << 4) | input;        // Add ones and return answer
}

int main()
{
  
  // initalize the Watchdog Timer
       WDTCR=0x18;  
       WDTCR=0x00; 
  
      //    MCUCR= (1<<PUD);
       
         //Initialize UART
      USART_init();
      Timer0_init();
      Timer1_init();
     // Timer2_init();
      
      // Setup the Watchdog Timer
       WDTCR=0x18;  
       WDTCR=0x0f; // Set bit  WDE=1 and WDP = 2,2 sec
       
       // USART_Transmit( 0x00);  
 USART_Transmit('S'); 
 USART_Transmit('t');
 USART_Transmit('a');
 USART_Transmit('r');
 USART_Transmit('t');
    
    
     //initialize portB
      
      sbi(DDRB,0);
      sbi(PORTB,0);
      sbi(DDRB,1);
      sbi(PORTB,1);
      sbi(DDRB,2);
      cbi(PORTB,2);
     sbi(DDRB,3);
     
     sbi(TCCR1B,CS10);  //start Timer
     cbi(TCCR1B,CS11);
     cbi(TCCR1B,CS12);
     sbi(TIMSK,OCIE1A);
     sbi(TIMSK,TOIE1);
     
     B=10;
     freq=550;
    CalcParameterTimer1CTC_Mode(freq,B);
     OCR1A=X1;
     TCNT1=0;
     
     
     
   
   //  OCR1B=X1;
      asm("SEI");

    // OCR1A=0x2f;
   //  TCNT1=0x7f;
     while (1) {
       if (flagBufFull==true){
        
                      
     B=0;
     B=((bufUART[8]&0x0f)*10+(bufUART[10]& 0x0f));
  
     freq=0;
        
    freq=(unsigned long int) ((bufUART[3] & 0x0f)*1000+(bufUART[4]& 0x0f)*100+(bufUART[5] & 0x0f)*10+(bufUART[6]& 0x0f));   
        
     CalcParameterTimer1CTC_Mode(freq,B);
   // flagBufFull=false;
       }

    
       /* Reset Watchdog */
   asm("WDR"); 
 //  sbi(PORTB,0);
 //  pause();
 //  cbi(PORTB,0);   
    
    // __watchdog_reset();
  }
    
       
       
  
  //return 0;
}
//#pragma vector = TIMER2_COMPA_vect
//__interrupt void Timer2_COMPA(void)
//{
 // cbi(TCCR1A,FOC1A);
//  TCNT1H = 0xfc; //setup TCNT1= 64513 
//  TCNT1L = 0x01;
  
   //tempUDR = UDR;
 // USART_Transmit( tempUDR);
   //PORTB^=BIT(2); //for testing
  //  TCNT1=65506;
//}


#pragma vector = TIMER2_OVF_vect 
__interrupt void Timer2_OVF(void)
{
   //tempUDR = UDR;
 // USART_Transmit( tempUDR);
}

#pragma vector = TIMER1_COMPA_vect
__interrupt void Timer1_COMPA(void)
{
     TCNT1H=VarTCNT1>>8;
     TCNT1L=VarTCNT1;
   
     // TCNT1=TCNT1+1;
   //TCNT1=VarTCNT1;
   
  // sbi(TCCR1A,FOC1A);
 //   cbi(TIMSK,OCIE1A);
    //TCNT1=X2;
    
//  cbi(TCCR1A,FOC1A);
 // OCR1AH = 0x03; // Output Compare Register 1 AH
 // OCR1AL = 0xff; //Output Compare Register 1 AL
 // TCNT1H=0xfc;
//  TCNT1L=0x00;
 // cbi(PORTB,1);
  
// if (flagCompare) {OCR1A=X1;TCNT1=2;flagCompare=0;}
 //      else {OCR1A=X2;TCNT1=27;flagCompare=1;}
  
  
//  if (flagCompare==1) {OCR1A=0x2f;TCNT1=0;flagCompare=0;}
 // else {OCR1A=0x0f;TCNT1=0;flagCompare=1;}
  
  
  
  //  TCNT1=61488;; //setup TCNT1= 64513 
 // TCNT1L = 0x01;
  
   //tempUDR = UDR;
 // USART_Transmit( tempUDR);
   //PORTB^=BIT(2); //for testing
  //  TCNT1=65506;
}

#pragma vector = TIMER1_OVF_vect 
__interrupt void Timer1_OVF(void)
{
  sbi(TCCR1A,FOC1A);
   //TCNT1=8;
 // cbi(TIFR,OCF1A);
 // sbi(TIMSK,OCIE1A);
  
  
 // OCR1AH = 0x00; // Output Compare Register 1 AH
 // OCR1AL = 0x3f; //Output Compare Register 1 AL
 
 // sbi(PORTB,1);
  
  // TCNT1=61488;; //setup TCNT1= 64513
 //  sbi(PORTB,1);
   //tempUDR = UDR;
 // USART_Transmit( tempUDR);
   //PORTB^=BIT(2); //for testing
  //  TCNT1=65506;
}

#pragma vector = TIMER0_OVF_vect 
__interrupt void Timer0_OVF(void)
{
  CounterTimer0=CounterTimer0+1;
  PORTB^=BIT(3); //for testing
  
  if (CounterTimer0==500) {PORTB^=BIT(2);CounterTimer0=0;} //for led
  TCNT0=0x7c;
    
    
   //tempUDR = UDR;
 // USART_Transmit( tempUDR);
}


#pragma vector = USART_RXC_vect 
__interrupt void UartRxEnd(void)
{
   tempUDR = UDR;
   if (tempUDR==0x24){bufUART[0]=tempUDR;flagBufFull=false;i=i+1;}
   else {bufUART[i]=tempUDR;i=i+1;}
   if (tempUDR==0x2a){flagBufFull=true;i=0;}
  USART_Transmit( tempUDR);
}
