/*************************************************************
** Attiny TXD Modulation fuer IR LEDs
*
* Das TXD Signal abtasten und wenn 0 das Output Signal an PA6 frei schalten
* Korrektur des TXD Signals da der IR Empfänger unterschiedliche Verzögerungen hat:
* von 1 auf 0 = 200 µsek, von 0 auf 1 = 260 µsek, d.h. von 1 auf 0 wird um 60µsek verzögert.   
* 
*
* Interupt Belegung                             wo              warum
* -------------------------------------------------------------------------------------------
* INT0        External Interrupt Request 0                             
* PCINT0      Pin Change Interrupt Request 0
* PCINT1      Pin Change Interrupt Request 1
* WDT         Watchdog Time-out
* TIM1_CAPT   Timer/Counter1 Capture Event
* TIM1_COMPA  Timer/Counter1 Compare Match A
* TIM1_COMPB  Timer/Counter1 Compare Match B
* TIM1_OVF    Timer/Counter1 Overflow
* TIM0_COMPA  Timer/Counter0 Compare Match A    
* TIM0_COMPB  Timer/Counter0 Compare Match B
* TIM0_OVF    Timer/Counter0 Overflow
* ANA_COMP    Analog Comparator
* ADC ADC     Conversion Complete
* EE_RDY      EEPROM Ready
* USI_STR     USI START
* USI_OVF     USI Overflow
*
* Prozessor:  ATtiny24 oder Attiny25
* Frequenz:   8,000 MHz (interner Clock)
*
* -------------------------------------------------------------------------------------------
* Pin Belegung Attiny24 
*                                            +----------------+
*                                       VCC -|1     XXX     14|- GND
*                                            |                |
*                   (PCINT8/XTAL1/CLKI) PB0 -|2             13|- PA0 (ADC0/AREF/PCINT0)
*                                            |                |
*                        (PCINT9/XTAL2) PB1 -|3             12|- PA1 (ADC1/AIN0/PCINT1)
*                                            |                |
* Reset ISP          (PCINT11/RESET/dW) PB3 -|4             11|- PA2 (ADC2/AIN1/PCINT2)
*                                            |                |
* TXD (in)    (PCINT10/INT0/OC0A/CKOUT) PB2 -|5             10|- PA3 (ADC3/T0/PCINT3)     
*                                            |                |
*                (PCINT7/ICP/OC0B/ADC7) PA7 -|6              9|- PA4 (ADC4/USCK/SCL/T1/PCINT4)
*                                            |                |
* f0     (PCINT6/OC1A/SDA/MOSI/DI/ADC6) PA6 -|7              8|- PA5 (ADC5/DO/MISO/OC1B/PCINT5) 
*                                            +----------------+
* -------------------------------------------------------------------------------------------
* Pin Belegung Attiny25 
*                                            +----------------+
* Reset ISP      (PCINT5/RESET/ADC0/dW) PB5 -|1     XXX      8|- VCC
*                                            |                |
* TXD (in)(PCINT3/XTAL1/CLKI/OC1B/ADC3) PB3 -|2              7|- PB2 (SCK/USCK/SCL/ADC1/T0/INT0/PCINT2)
*                                            |                |
*         (PCINT4/XTAL2/CLKO/OC1B/ADC2) PB4 -|3              6|- PB1 (MISO/DO/AIN1/OC0B/OC1A/PCINT1)
*                                            |                |
*                                       GND -|4              5|- PB0 (MOSI/DI/SDA/AIN0/OC0A/OC1A/AREF/PCINT0)
*                                            +----------------+
*--------------------------------------------------------------------------------------------
* FUSE: Attiny24   FF DF E2
*       Attiny25   FF DF E2
* -------------------------------------------------------------------------------------------
* 29.10.2010 li modulation fuer TXD von nibobee
* 15.11.2010 li fuer attiny24 oder attiny25 (testboard)
*/

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <math.h>
#include "../../abc/basis.h"

static void timer1_init( void );

/*###########################################################################
 * Main
 */
int main(void)
{
   unsigned char txd; 
   unsigned char txd_old = 0xff; 
   
#if defined(__AVR_ATtiny24__)   
   DDRB  &= ~BIT2;                     // Input TXD
   PORTB |= BIT2;                      // Input mit internem Pullup Widerstand  
#endif  
 
#if defined(__AVR_ATtiny25__)   
   DDRB  &= ~BIT3;                     // Input TXD
   PORTB |= BIT3;                      // Input mit internem Pullup Widerstand  
#endif   

   timer1_init();
   
   sei();                              // enable int
   
	
   // ++++++++++++++++++++++++++++++++ Main LOOP ++++++++++++++++++++++++++++
   // ++++++++++++++++++++++++++++++++ Main LOOP ++++++++++++++++++++++++++++
   // ++++++++++++++++++++++++++++++++ Main LOOP ++++++++++++++++++++++++++++
	for(;;)
	{
#if defined(__AVR_ATtiny24__)     
	   txd = PINB & BIT2;                 // txd Signal Wert auslesen 
      if ( txd != txd_old )
      {
         txd_old = txd;
         if ( txd )                      // 0 -> 1 = inaktiv
         {
            DDRA &= ~BIT6;               // Port OUTPUT ausschalten
         }
         else
         {
            _delay_us(50);               // 1 -> 0, delay 50µ sek
            DDRA |= BIT6;                // Port OUTPUT = PWM 36 kHz einschalten
         }
      }
#endif
#if defined(__AVR_ATtiny25__) 
      txd = PINB & BIT3;                 // txd Signal Wert auslesen
      if ( txd != txd_old )
      {
         txd_old = txd;
         if ( txd )                      // 0 -> 1 = inaktiv
         {
            DDRB &= ~BIT1;               // Port OUTPUT ausschalten
         }
         else
         {
            _delay_us(50);               // 1 -> 0, delay 50µ sek
            DDRB |= BIT1;                // Port OUTPUT = PWM 36 kHz einschalten
         }
      }      
#endif
   }
   return 0;           // dummy
}



/*****************************************************************************
**  Timer1 generate 36000 Hz
**  Clock intern auf 8 MHz
*/
static void timer1_init( void )
{
#if defined(__AVR_ATtiny24__)   
   unsigned char vt;
   unsigned int top, comp;
   float ftarget;                     // Zielfrequenz
   float fteiler;                     // Teiler
           
   ftarget = 36000.0;                 // Zielfrequenz
   fteiler = 8000000.0 / ftarget;
      

   if ( fteiler > 65535.0 )
   {
      vt = 3;                      // Vorteiler auf 64
      fteiler /= 64.0;
   }
   else
   {
      vt = 1;
   }

   
      
   top = fteiler;                     // timer 1 count bis top
   comp = top / 2;                    // Fehlwert 50 % PWM  
   TCCR1B = (1<<WGM13)| (1<<WGM12);   // Mode 14 setzen
   TCCR1B |= vt;
   TCCR1A |= (1<<COM1A1) | (1<<COM1A0) | (1<<WGM11); // OC1A setzen wenn compare match
   OCR1A = comp;
   ICR1 = top;
   TCNT1 = 0;
#endif 

#if defined(__AVR_ATtiny25__) 
 
   TCCR1 |= (1<<CTC1) + (1<<PWM1A);   // clear TCNT1 wenn match mit OCR1C 
   TCCR1 |= 1;                        // vorteiler auf 1 setzen
   TCCR1 |= (1<<COM1A0) ;             // TOGGLE OC1A wenn compare match
   GTCCR |= (1<<FOC1A) ;              // force output compare match
   OCR1A = 111;
   OCR1C = 222;
   TCNT1 = 0;
   
#endif     
}

