#include <mega88p.h>
#include <delay.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define musor_time                    50      //  time (in seconds )=   seconds/10 (for example 100 is 10 seconds)
#define led_blink_time                30
#define led_interval_time             20      // interval, while LED is liting, when the musor_time will finished
 
volatile bit flag_led=0;
volatile bit flag_rx=0;
volatile bit flag_musor=0;          //флаг генеразии мусора
volatile bit flag_interval=0;        //флаг интервала горения led
volatile bit flag_ledblink=0;     
volatile unsigned int musor_counter=0;
volatile unsigned int interval_count=0;
//volatile unsigned int seconds=0;



eeprom unsigned int enumb;


unsigned int numb;
 

// Timer1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)                       
{
// Reinitialize Timer1 value
TCNT1H=0x3CB0 >> 8;
TCNT1L=0x3CB0 & 0xff;
// Place your code here

++musor_counter;
//++seconds;

//
if (musor_counter>led_blink_time &&  musor_counter<musor_time)                 //запуск мигания светодиода
 {
    flag_ledblink=1;                  
    if (flag_led==0)
    {
     flag_led=1;
     }
    else
    {
    flag_led=0;
    }  
 }

//
if (musor_counter==musor_time) {flag_musor=1; flag_interval=1;}       //start musor generation 
if (flag_interval==1)  {++interval_count;}
}



//leds
//void leds_on(void)
//{
//    DDRD=0x40;
//    PORTD=0x40; 
//}
//
//void leds_off(void)
//{
//    DDRD=0x00;
//    PORTD=0x00; 
//}

void led_blink(void)
{ 

     if (flag_ledblink==1 && flag_led==1)
     {
       PORTD=0x40;
     }
     else
      {
       PORTD=0x00;
      }
}

void led_interval(void) //led is on, until two seconds have passed since the musor_counter was 100
{
  PORTD=0x00;   
    if (flag_interval==1)
    {
         if (interval_count<led_interval_time) 
     {
      
      

                PORTD=0x40;
     }
         else{flag_interval=0; interval_count=0; }                   
     }
     
}
#ifndef RXB8
#define RXB8 1
#endif

#ifndef TXB8
#define TXB8 0
#endif

#ifndef UPE
#define UPE 2
#endif

#ifndef DOR
#define DOR 3
#endif

#ifndef FE
#define FE 4
#endif

#ifndef UDRE
#define UDRE 5
#endif

#ifndef RXC
#define RXC 7
#endif

#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<DOR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

// USART Receiver buffer
#define RX_BUFFER_SIZE0 640
char rx_buffer0[RX_BUFFER_SIZE0];

#if RX_BUFFER_SIZE0<256
unsigned char rx_wr_index0=0,rx_rd_index0=0,rx_counter0=0;
#else
unsigned int rx_wr_index0=0,rx_rd_index0=0,rx_counter0=0;
#endif

// This flag is set on USART Receiver buffer overflow
//bit rx_buffer_overflow0;



//
//// USART Receiver interrupt service routine
//interrupt [USART_RXC] void usart_rx_isr(void)
//{
//char status,data;
//status=UCSR0A;
//data=UDR0;
//if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
//   {
//   rx_buffer0[rx_wr_index0]=data;
//   if (++rx_wr_index0 == RX_BUFFER_SIZE0) rx_wr_index0=0;
//   if (++rx_counter0 == RX_BUFFER_SIZE0)
//      {
//      rx_counter0=0;
////      rx_buffer_overflow0=1;
//      };
//      flag_rx=1;
//   };
//}










// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSR0A;
data=UDR0;

if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) {   
        if (rx_counter0 < RX_BUFFER_SIZE0) {
           ++rx_counter0;
           flag_rx=1;
            rx_buffer0[rx_wr_index0]=data;
            if (++rx_wr_index0 == RX_BUFFER_SIZE0)  rx_wr_index0=0;
        }
    }
    
}

#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART Receiver buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
char data;
while (rx_counter0==0);
data=rx_buffer0[rx_rd_index0];
if (++rx_rd_index0 == RX_BUFFER_SIZE0) rx_rd_index0=0;
#asm("cli")
--rx_counter0;
   
#asm("sei")
return data;
}
#pragma used-
#endif

// USART Transmitter buffer
#define TX_BUFFER_SIZE0 32
char tx_buffer0[TX_BUFFER_SIZE0];

#if TX_BUFFER_SIZE0<256
unsigned char tx_wr_index0=0,tx_rd_index0=0,tx_counter0=0;
#else
unsigned int tx_wr_index0=0,tx_rd_index0=0,tx_counter0=0;
#endif

// USART Transmitter interrupt service routine
interrupt [USART_TXC] void usart_tx_isr(void)
{
if (tx_counter0)
   {
   --tx_counter0;
   UDR0=tx_buffer0[tx_rd_index0];
   if (++tx_rd_index0 == TX_BUFFER_SIZE0) tx_rd_index0=0;
   };
}

#ifndef _DEBUG_TERMINAL_IO_
// Write a character to the USART Transmitter buffer
#define _ALTERNATE_PUTCHAR_
#pragma used+
void putchar(char c)
{
while (tx_counter0 == TX_BUFFER_SIZE0);
#asm("cli")
if (tx_counter0 || ((UCSR0A & DATA_REGISTER_EMPTY)==0))
   {
   tx_buffer0[tx_wr_index0]=c;
   if (++tx_wr_index0 == TX_BUFFER_SIZE0) tx_wr_index0=0;
   ++tx_counter0;
   }
else
   UDR0=c;
#asm("sei")
}
#pragma used-
#endif

// Standard Input/Output functions


// Declare your global variables here

void fs_print(char flash *buf)
{
    int n=0;
    
    while(buf[n] != 0)
    {   putchar(buf[n++]);
    }
}


void setnumb(void)
{      
   
unsigned char buff[];
unsigned char ebuff[];
unsigned int lbuff;
unsigned int ibuff; 
unsigned int tmp=0;
unsigned int l=0;
     
               lbuff=0;       
               ibuff=0;  
               

                    do   
                    {        
                    buff[ibuff]=getchar(); 
                    if (buff[ibuff]<0x7F && buff[ibuff]>0x1F || buff[ibuff]=='\n')
                        { 
                        ibuff++;       
                        }      
                    }while (ibuff<7);
                     buff[ibuff]=0;
                         
               
                //сравниваем строки с буфером   
                if (strcmpf(buff,"status?")==0) 
                 { 
                     printf("%u",numb);
                     
                     fs_print(". ok\r\n");
                     tmp=1; 
                    
                 } 
                if (strcmpf(buff,"number?")==0) 
                 { 
                     printf("%u",numb);
                     fs_print("\r\n\r\n");
                     tmp=2; 
                     
                 } 
                 if (strcmpf(buff,"setnumb")==0) 
                    {
                       lbuff=0; 
                       l=0;
                       while (1) {
                           ebuff[lbuff]=getchar();
                           putchar(ebuff[lbuff]);
                              
                           if(ebuff[lbuff]<0x30 || ebuff[lbuff]>0x39) 
                           {
                               if(ebuff[lbuff]==0xA) { tmp=3 ; fs_print("\r\nsetnumb ok\r\n"); break;}
                               
                               if (ebuff[lbuff]!=0xD) {fs_print("_error numb_");} 
                           } 
                           else 
                           {
                               l=(ebuff[lbuff]-0x30)+(l*10);
                               lbuff++;
                           }
                      } 
                      
                                          
                      numb=l;         //L !! not 1 !!
                      enumb=numb;
                     

                     tmp=4;
                     
                    } 
                 if (tmp==0)  {fs_print("\r\nerror cmd\r\n");}
                 delay_ms(30);               
                               
} 
            
 
void put32(void)
{
unsigned int n=0;
unsigned int m=0;
n=0;            
m=0x61;
             while (n!=26) 
             {         
              putchar(m);
              m++; 
              n++;        
             }; 
n=0;
m=0x41;
             while (n!=6) 
             {         
              putchar(m);
              m++; 
              n++;        
             };


}



void musor(void)
{
unsigned int rnd;


unsigned int i=0;



rnd=rand()& 0x05;

       fs_print("\r\n_");            
        switch (rnd) 
       
    {
      
        case 0:     
             
             fs_print("32"); fs_print("_\r\n");
             put32();

            break;    
            // ..................... 
        case 1:  
             fs_print("64"); fs_print("_\r\n");
             for (i=0; i<2; i++)
                {put32();}
            break;  
            // ..................... 
        case 2:    
             fs_print("128"); fs_print("_\r\n");
             for (i=0; i<4; i++){put32();}

            break; 
            // ..................... 
        case 3:        
             fs_print("256"); fs_print("_\r\n");
             for (i=0; i<8; i++){put32();}

            break;
            // ..................... 
        case 4:   
             fs_print("512"); fs_print("_\r\n");
             for (i=0; i<16; i++){put32();}

            break; 
            // ..................... 
          case 5:   
             fs_print("1024"); fs_print("_\r\n");
             for (i=0; i<32; i++){put32();}

            break; 
            // .....................
        
           
        default:
        fs_print("default");
            break;     
    } 
      
   
   
    
}



      
void main(void)
{
 numb=enumb;
 srand(23) ;

// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 62,500 kHz
// Mode: Normal top=FFh
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x00;
TCCR0B=0x03;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 500,000 kHz
// Mode: CTC top=OCR1A
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x0A;
TCNT1H=0x3C;
TCNT1L=0xB0;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=FFh
// OC2A output: Disconnected
// OC2B output: Disconnected
ASSR=0x00;
TCCR2A=0x00;
TCCR2B=0x00;
TCNT2=0x00;
OCR2A=0x00;
OCR2B=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// Interrupt on any change on pins PCINT0-7: Off
// Interrupt on any change on pins PCINT8-14: Off
// Interrupt on any change on pins PCINT16-23: Off
EICRA=0x00;
EIMSK=0x00;
PCICR=0x00;

// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x00;
// Timer/Counter 1 Interrupt(s) initialization
TIMSK1=0x01;
// Timer/Counter 2 Interrupt(s) initialization
TIMSK2=0x00;

//// USART initialization
//// Communication Parameters: 8 Data, 1 Stop, No Parity
//// USART Receiver: On
//// USART Transmitter: On
//// USART0 Mode: Asynchronous
//// USART Baud Rate: 4800
//UCSR0A=0x00;
//UCSR0B=0xD8;
//UCSR0C=0x06;
//UBRR0H=0x00;
//UBRR0L=0x33;

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART0 Mode: Asynchronous
// USART Baud Rate: 56000
UCSR0A=0x00;
UCSR0B=0xD8;
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x08;


// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
ADCSRB=0x00;;

// Global enable interrupts
#asm("sei")
 DDRD=0x40; 

while (1)
         {  
         
    led_blink();
      if (flag_rx==1) {setnumb();   flag_rx=0;  } 
     
      if (flag_musor==1) 
      {  
      PORTD=0x40;
          
         
          musor();
          flag_musor=0;
          flag_ledblink=0;
          musor_counter=0;                     
        PORTD=0x00;
      }   
     
   led_interval();
       //printf("%u\r\n", );                       
      };
}