Zurück (C) Christof Ermer, Regensburg



30.01.2014


V3 - 2 Kanalige Servosteuerung für Lambda /4tel Plättchen
Für kleines Labor   mit µC=ATTiny2313
Christof Ermer 30.01.2014


Youtube : http://youtu.be/yundxoedF1s







UART 1200  Baud, 8Bit, 1 Stop, kein Hardware Handshake

Intern läuft der µProzessor auf 16Mhz. / 8  / 50Hz  = 40000
FUSES / 8 / WDTON, BROWNOUT 4.3Volt

der Takt wird durch 40.000 geteilt, was einen 50Hz PWM erzeugt.
Dieser passt gut zu Servos
PWM kann von 0 bis 49999 ausgegeben werden.
Servos arbeiten jedoch etwa vom 0.8 Millisekunden bis 2 Millisekunden.

Also ist nur ein PWM von 2000 bis  4000 Sinnvoll.
Nach dem Einschalten wird 3000  ausgegeben…(~etwa Mitte)
Es ist explizit erst der PWM Wert zu stellen und dann mit 3PO einzuschalten.
Format des Befehls:
PING<13> -à „Pong“
NEU Dazugekommen:
Device <13>      à          "Blaue Box-Servo Lambda/4tel"

PWM1,{WERT} Kanal 1 wird auf WERT gestellt  + Carriage Return
PWM2,{WERT} Kanal 2 wird auf WERT gestellt + Carriage ReturGETMODE <13> à  Byterückgabe gu8Mode ,
#define               MODE_PREFIX_ENABLE               0x01
#define               MODE_TX_TRAFFIC                       0x02
#define               MODE_SERVOS_ACTIVE              0x04
#define               MODE_SERVOS_POWERFALLBACK        0x08

STAT1 oder Stat2 <13>   à gibt gewählte reale PWM zurück 2000….3000
PF, PO Servos POWER OFF, POWER ONICR,[0..65535]  Stellt die Zeit Basis des  Rückstell-Vergleichstimers um. Default 20000.
Jede Textausgabe wird mit einem CarriageReturn ( 13 ) abgeschlossen.
Jeder Input-Befehl wird mit einem CR ( 13 ) akzeptiert.Sinvolle Sequenz:
PO<13>  (Power On)
Pwm1,Value [1000..5000]; PO (Power on);
Warten ~1Sekunde;
 PF<13>   (Power Off)
 DEFAULT VOM STARTWEG IST
AutoPower OFF ~1 Sekunde eingestellt
PWM = 3000 = MITTE
Also muss selbst mit PWM1,xxx ~2000 der Servo gestellt weren

//LINKSANSCHLAG pwm1,2000
//RECHTSSANSCHLAG pwm1,4000  23mS
// PWM1,2000 1MS
// PWM1,4000 2MS
/*
PWM werden im 16 Bit Timer mit OCR1A(B erzeugt
*/


//  1200 BAUD

//------------------------------------------------------------------------------
// Programmed by Christof Ermer
//------------------------------------------------------------------------------

///SYSINFO
#define DATUM        "24.01.2014"
#define FUNKTION    "Lmabda Viertel Dual Servo V3 mit ATTiny2313"
#define AUTOR        "Christof Ermer"
#define BAUDRATE    "1200"
//FUSE 16MHz BrownOut=> L=0xFF H=0xD9
//http://www.engbedded.com/fusecalc
// ORG NewChip Tiyn2313  FUSE  0x64 0xDF
//

/*
ftoa braucht Speicher wie sau

libusb0.dll
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=373283
!!!!!!!!!!!!!!
Unter Windows NT,2000,XP,Vista? braucht AVRDUDE einen Treiber
GIVEIO.SYS, um auf die Ports zugreifen zu können.
Du kannst den Treiber durch den Aufruf der Batchdatei
WinAVR\bin\install_giveio.bat installieren.



in PonyProg Häckcen Setzen
Bits in PDF sind umzudrehen
eine 0(PDF) ist ein Häckchen setzen in PonyProg,
eine 1(PDF) ist Kästchen frei,

WDTON = V Watchdog timer oN
//4.3Volt
Bodlevel 2 = X
Bodlevel 1 = V
Bodlevel 0 = V
#define UART_BAUD_RATE    9600
#define F_CPU    16000000
*/

/*
in io.h
#elif defined (__AVR_ATtiny2313__)
#include <avr/iotn2313.h>
*/

#include <avr/io.h>
#include <ctype.h>
#include <inttypes.h>
#include <avr\io.h>
#include <avr\pgmspace.h> // <--#include <progmem.h>

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdarg.h>
#include <string.h>
#include <avr\interrupt.h>  // obsolete #include <avr\signal.h>

#include <avr\eeprom.h>   

//ACHTUNG STELLT OBSOLETE Procedure in header wieder her
#include <compat\deprecated.h>

//#include <avr\twi.h> /* Note [1] */  // NEUE DATEIVERSION_STR BEUNTZEN
//#include <avr\signal.h> //#include <signal.h>

#include <avr\wdt.h>
//Produziert Fehler...
#include <util\delay.h>    //_delay_loop_1 _delay_loop_2 delay_ms

#include "main.h"        //with Hardware assigns
#include "uart.h"

#ifndef CTC1
#define CTC1 WGM12              // for compatibility with ATmega
#endif

void Wait100ms(void);

#ifdef USE_TOGGLE_FLAG
void ToggleTEST_BIT(uint8_t ucCnt);
#endif

#ifdef UART_USE_ENABLED
void UART_TXRX_Check(void);
void ResetRxBuff(void);
#endif

//CONSTANT ARRAYs IN .TEXT = ROM ARREA   .DATA IST SRAM !! .BSS SRAM
//const char MCA_VERSION[] PROGMEM = VERSION;
#ifdef TEXT_SERVICE_USE_ENABLED
void CheckOrder(char* pcStr);
void PrintCR(void);
#endif

// GLOBALE VARIABLEN

#ifdef UART_USE_ENABLED
volatile char* gpcRxPars;
static char gcaRxStr[RX_STRMAX + 1]; //+1 for the 0
#endif
#ifdef TEXT_SERVICE_USE_ENABLED
//static char gcaNumStr[NUMMAX + 1]; //+1 for the 0
static char gcaStr[STRMAX + 1]; //+1 for the 0
static COMMAND_TYPE gsCmd;
#endif


static uint32_t    gu32_Ticks; //  T2 timeCounter, only NN_Counter for Keypressings
static uint8_t    gu8Mode;

#ifdef TIMERxTICK_USED
// ****************************************************************
//volatile  SIGNAL(TIMER2_OVF_vect) //oder SIGNAL--INTERRUPT(SIG_OVERFLOW2) = mit SEI am Anfang
//SIGNAL( TIMER0_OVF_vect ) //oder SIGNAL--INTERRUPT(SIG_OVERFLOW2) = mit SEI am Anfang
SIGNAL( SIG_WDT_OVERFLOW  )
// *******************************************************************
{
sei();
#ifdef UART_USE_ENABLED
UART_TXRX_Check();    //IMMER VORNAHANDEN !! IN ALLEN LOOPS DIE ZEIT BRAUCHEN
#endif
};
#endif


// *******************************************************************
void Wait100ms(void)
// *******************************************************************
{
uint8_t u8Z;
for(u8Z=0; u8Z < 100; u8Z++)
    {
    _delay_ms(1);
    wdt_reset();
    };
};




#ifdef USE_TOGGLE_FLAG
// ****************************************************************
void ToggleTEST_BIT(uint8_t ucCnt)
// ****************************************************************
{ // #include <util\delay.h>  muss da sein
uint8_t ucNN;
for(ucNN=0; ucNN < ucCnt; ucNN++)
    {
    SET_TESTBIT_MAC;
    _delay_us(1);
    CLR_TESTBIT_MAC;
    _delay_us(1);
    };
};
#endif


#ifdef UART_USE_ENABLED
// *******************************************************************
void UART_TXRX_Check(void)
/*   
* Get received character from ringbuffer
* uart_getc() returns in the lower byte the received character and
* in the higher byte (bitmask) the last receive error
* UART_NO_DATA is returned when no data is available.
*/
// *******************************************************************
{
uint16_t uiRxUart = uart_getc();//!FETCH ALLWAYS BYTE FROM RX RINGBUFF INTERRUPT!
if ( !(uiRxUart & UART_NO_DATA) )  //0x0100
    {
//   * new data available from UART
//  * check for Frame or Overrun error
#ifdef UART_ERRORMSG
    if( uiRxUart & (UART_FRAME_ERROR | UART_OVERRUN_ERROR | UART_BUFFER_OVERFLOW) )
        {
        ResetRxBuff();
        uart_init( UART_BAUD_SELECT(UART_BAUD_RATE, F_CPU) );// !! Init UART interface
// Framing Error detected, i.e no stop bit detected
        uart_puts_p(PSTR("UartEr");
        uart_putc(13);
        };
#endif
//NOW SELCT ACTION FROM ORDER
//Check CR
    if(gpcRxPars < (gcaRxStr + RX_STRMAX))    //ENDANSCHLAG ERREICHT ?
        {
        switch( (unsigned  char)uiRxUart  )
            {
            case 10: // order!! from Terminal
                {
                break;
                };
            case 13: // order!! from Terminal
                {
#ifdef COMMANDS_ENABLED
                CheckOrder(gcaRxStr);
#endif               
//uart_init( UART_BAUD_SELECT(UART_BAUD_RATE, F_CPU) );//!! Init UART interface               
                ResetRxBuff();
                break;
                };                              
            default: //Accumulate
                {
            //Accumulate String only to gcaRxStr with uiAAA Parser
                *gpcRxPars++ = (unsigned  char)(uiRxUart & 0x0FF);//Append rxByte
                *gpcRxPars = 0; //ZERO carry
                };
            };//switch
        }// if (pcRxPars < (gcaRxStr + RXSTRMAX))
    else  // To much data Rx, than clear simple all
        {
     //overflow of RX clears all
        ResetRxBuff();    // Clear Rx Parspointer in Buff an terminate RxStr with 0
        };//if(gpcRxPars < (gcaRxStr + RXSTRMAX))
// ENDE DER RX EMPFANGSAUSWERTUNG
    };
};
#endif



#ifdef UART_USE_ENABLED
// *******************************************************************
void ResetRxBuff(void)
// *******************************************************************
{
while(!(uart_getc() & UART_NO_DATA)){};
gpcRxPars = gcaRxStr; // Set parse pointer back;
*gpcRxPars = 0;    //clear Rx
};
#endif


#ifdef COMMANDS_ENABLED

// *******************************************
void TxOk(void)
// *******************************************
{
uart_puts_p( PSTR("OK") );
uart_putc( 13 );
};

// *******************************************************************
void CheckOrder(char *pcStrOrder) //von gcaRxStr
// *******************************************************************
{ //INPUT ERWARTET INDER FOR "BEFEHL,WERT" BSP: "SFR,1000"
//uint16_t uiCnt =0;
char * pStrTok; // für strtok_r
char * pucStrEnd = &pcStrOrder[ strlen(pcStrOrder) ]; // Stelle POINTER auf \0 Ende  // kein unsigned char*   

strcpy_P(gcaStr, PSTR(",")); //HILFSWEISE gcaStr für ","
if( (pStrTok = strtok_r( (pcStrOrder), gcaStr, &pucStrEnd)) != NULL)
    {   
    strcpy(gsCmd.ucaCmd, pStrTok);
    }
else
    {
    *gsCmd.ucaCmd = 0;   
    };
gsCmd.uiCmdVal_1 = 0;

if( (pStrTok = strtok_r( NULL, gcaStr, &pucStrEnd)) != NULL)//Hole nun einen Value nach "#3,COMMAND,VALUE
    {
    gsCmd.uiCmdVal_1 = atol( pStrTok );// Und dann TO long
    };

//===================================================================================


if(!strcasecmp_P( gsCmd.ucaCmd, PSTR("PING")))
    {
    uart_puts_p( PSTR("Pong") );
    uart_putc( 13 );
    };

if(!strcasecmp_P( gsCmd.ucaCmd, PSTR("DEVICE")))
    {
    uart_puts_p( PSTR("Blaue Box-Servo Lambda/4tel") );
    uart_putc( 13 );
    };

if(!strcasecmp_P( gsCmd.ucaCmd, PSTR("PWM1")))
    {
    PWM_ENABLE();
    gu8Mode |= MODE_SERVOS_ACTIVE;
    OCR1A = gsCmd.uiCmdVal_1;
    gu32_Ticks = 0;
   
//uart_puts_p( PSTR("OCR1=") );uart_puts( utoa(OCR1A, gcaStr, 10) );uart_putc( 13 );
    };
   
if(!strcasecmp_P( gsCmd.ucaCmd, PSTR("PWM2")))
    {   
    PWM_ENABLE();
    gu8Mode |= MODE_SERVOS_ACTIVE;
    OCR1B = gsCmd.uiCmdVal_1;
    gu32_Ticks = 0;
//uart_puts_p( PSTR("OCR2=") );uart_puts( utoa(OCR1B, gcaStr, 10) );uart_putc( 13 );
    };
   
if(!strcasecmp_P( gsCmd.ucaCmd, PSTR("STAT1")))
    {
    uart_puts( ltoa( OCR1A, gcaStr, 10 ) );
    uart_putc( 13 );
    };
   
if(!strcasecmp_P( gsCmd.ucaCmd, PSTR("STAT2")))
    {   
    uart_puts( ltoa( OCR1B, gcaStr, 10 ) );
    uart_putc( 13 );
    };
   
if(!strcasecmp_P( gsCmd.ucaCmd, PSTR("PO")))
    {
    PWM_ENABLE();
    gu8Mode |= MODE_SERVOS_ACTIVE;
    gu32_Ticks = 0;
    };
   
if(!strcasecmp_P( gsCmd.ucaCmd, PSTR("PF")))
    {
    PWM_DISABLE();
    gu8Mode &= ~MODE_SERVOS_ACTIVE;
    };
   
if(!strcasecmp_P( gsCmd.ucaCmd, PSTR("GETMODE")))
    {
    uart_puts( ltoa( gu8Mode, gcaStr, 10 ) );
    uart_putc( 13 );
    };

if(!strcasecmp_P( gsCmd.ucaCmd, PSTR("SMASO"))) // Set Mode AUTo SERVO OFF
    {
    gu8Mode |= MODE_SERVOS_POWERFALLBACK;
    };

if(!strcasecmp_P( gsCmd.ucaCmd, PSTR("cMASO"))) // CLEAR Mode AUTo SERVO ON
    {
    gu8Mode &= ~MODE_SERVOS_POWERFALLBACK;
    };
   
if(!strcasecmp_P( gsCmd.ucaCmd, PSTR("ICR")))
    {   
    ICR1 = gsCmd.uiCmdVal_1;    //ändert die frequenz / jetzt 50Hz
    };

if(!strcasecmp_P( gsCmd.ucaCmd, PSTR("??")))
    {
    uart_puts_p( PSTR("Ping, PWM1/2,STAT1/2,GETMODE,SMASO,cMASO,TO,TF,ICR,??") );
    uart_putc( 13 );   
    };
   
ResetRxBuff();
 };
#endif


#

// *****************************************************
int main(void)
// *****************************************************
{
//static uint16_t uiNN;
//static uint32_t u32Now;
//static uint8_t u8Val;
//static uint16_t u16Val;
//INITS
//The global interrupt flag is maintained in the I bit of the status register (SREG). 
cli();
//Wichtige Schritte.. so bald wie möglich

//INIT HARDWARE
//8Bit
DDRB = PORTB_DDRX_OUTMASK;
//PORTB = PORTB_PRESET_PULLMASK;
//7Bit
DDRD = PORTD_DDRX_OUTMASK;   
//PORTD = PORTD_PRESET_PULLMASK;

MCUCR |= _BV(PUD); // Pullup OFF
WDTCSR |= _BV(WDIE); // 62,5/Sekunde = 16mS

#ifdef UART_USE_ENABLED
ResetRxBuff();
uart_init( UART_BAUD_SELECT(UART_BAUD_RATE, F_CPU ));// !! Init UART interface
#endif
sei();

#ifdef  USE_TOGGLE_FLAG
INIT_TESTBIT_REG_MAC;
CLR_TESTBIT_MAC;
#endif

PWM_DISABLE();
ICR1 = PWM_TEILER_FUER50HZ; // Fixed Top Value  /20000U für 8MHZ
OCR1A =  PWM1_DEFAULT_VAL;
OCR1B =  PWM2_DEFAULT_VAL;
//TCCR1A = COM1A1, COM1A0, COM1B1, COM1B0,-,-, WGM11, WGM10
//Clear OC1A/OC1B on CompareMatch  WGM11 , WGM10
//Fast PWM mode, Set OC1A/OC1B on TOP, WGM13:0 set to fats PWM
TCCR1A = _BV( COM1A1) | _BV( COM1B1) | _BV( WGM11 );

// TCCR1B = ICNC1,ICES1,-,WGM13,WGM12,CS12,CS11,CS10
//ClockSelect /8
TCCR1B =  _BV( WGM13 ) | _BV( WGM12 ) | _BV( CS11 );

//ClockSelect /0 aber mit /8 in FUSE  CKDIV8 hat Haekchen
//TCCR1B =  _BV( WGM13 ) | _BV( WGM12) | _BV(CS10);
wdt_enable(WDTO_2S); //Set 1.9Sec WatchDog ENABLE

// ************ MAIN LOOP FOR EVER *********************
uart_puts_p( PSTR("Lamda/4tel") );
uart_putc( 13 );
Wait100ms();
uart_puts_p( PSTR("1200 BAUD") );
uart_putc( 13 );


gu32_Ticks = 0;
gu8Mode |= MODE_SERVOS_POWERFALLBACK;

for (;;)  /* loop forever */
    {   
    sei();
    wdt_reset();   //WATCHDOG!
   
    gu32_Ticks++; // Fortlaufend !!

    if( (gu8Mode & MODE_SERVOS_POWERFALLBACK ) &&
            (gu8Mode & MODE_SERVOS_ACTIVE) &&
            (gu32_Ticks > 1000000UL) //1Million
        )
        {
        PWM_DISABLE();
        gu8Mode &= ~MODE_SERVOS_ACTIVE;
        };

#ifdef UART_USE_ENABLED   
    UART_TXRX_Check();
#endif
    }; // main   END END *************
};
// ******************* MAIN END ********************************************







#ifndef MAIN_HEADER  //Prevents multiple includes
#define MAIN_HEADER

/*
Watchdog kann Interrupt
jede menge ADC eingänge

http://www.rn-wissen.de/index.php/Avr-gcc
*/

//TickCounter  MUSS SEIN !!!
#define UART_USE_ENABLED
//#define PREFIX_ENABLE
#define COMMANDS_ENABLED
#define TEXT_SERVICE_USE_ENABLED
//#define UART_ERRORMSG
//#define SONDER_TEXT_SERVICE
//#define TIMERxTICK_USED

//#define USE_TOGGLE_FLAG




/*
Jedes Port hat drei Register
DDxN
PORTXn
PINxn
IF PortX ist INPUT an PORTX= set to 1, PullUP IS ENABLED
//sfr |= _BV(bit)  ---  sfr &= ~(_BV(bit))
*/

/*
Text verbraucht Speicher
Statt Pointer geht evtl auch diese Form
PSTR ( "So geht s auch in den Progspeicher" ); // aber ohne Namen)

#define MCA_CRLFSTR (const char) {CR,LF,0}
*/

#define STRMAX        16
#define RX_STRMAX    16

#define DELIMITER        ','
#define DELIMITERSTR    ","
#define COMAMNDSIZEMAX  16

#define LOW_NIPPEL_MASK        0x0F
#define HIGH_NIPPEL_MASK    0xF0

//TYPEN DEKLARATION
//Tastatur
typedef struct
    {
    char ucaCmd[COMAMNDSIZEMAX +1];
    unsigned int uiCmdVal_1;
//uint8_t ucCmdID;
    }COMMAND_TYPE;

//Hardwareassignment
//F_CPU  in makefile !!!
//CPU = 8000000UL
#define UART_BAUD_RATE 1200
//#define UART_BAUD_RATE    19200
//#define UART_BAUD_RATE    57600

//8Mhz / 2^16
//122,0703125
//0,008192
#define PULS_PER_SEcONDTick    122
#define PULS_500MS_Tick        61
#define PULS_250MS_Tick        25
#define PULS_100MS_Tick        13
#define PULS_50MS_Tick        6

//WDTCSR
//16mS = 62,5 interrupts/Sekunde =
#define WDT_TICK_SECOND 62
#define WDT_TICK_500MS    31
#define WDT_TICK_100MS    6

#define DISABLE_ALL_PULLUP_MC()    (SFIOR |= _BV(PUD))
#define ENABLE_ALLUP_SCL_MC()    (SFIOR &= ~(_BV(PUD)))


// 1 TICK = 1.4814814814814814814814814814815 ms
//NUR UNGEFÄHR
//BERECHUNG Xtime(ms) / 1.48....
#define TIMEOUT_1_5MS     1
#define TIMEOUT_2_9MS     2
#define TIMEOUT_4_4MS     3
#define TIMEOUT_10_3MS     7
#define TIMEOUT_100_7MS    68
#define TIMEOUT_500_7MS    338
#define TIMEOUT_1S         675        //!!  uint16_t
#define TIMEOUT_5S         3375    //!!  uint16_t

//REGISTER
#define TCCR0_FAST_PWM    0x48    //Mode 3
#define TCCR0_OC0_MODE    0x20    //Clear ON compare Match
#define TCCR0_OC0_DISCONNECT_MODE    0x00
#define TCCR0_CLK_STOP    0x00   
#define TCCR0_CLK_0        0x01   
#define TCCR0_CLK_8        0x02   
#define TCCR0_CLK_64    0x03   
#define TCCR0_CLK_256    0x04   
#define TCCR0_CLK_1024    0x05   
#define TCCR0_EXT_CLK_FALL_T0    0x06   
#define TCCR0_EXT_CLK_RISE_T0    0x07   

#define TCCR2_WGM_NORMAL        0x00
#define TCCR2_CTC_MODE            0x08 //0000 1000
#define TCCR2_COM_NORMALPORT    0x00
#define TCCR2_CLK_STOP            0x00
#define TCCR2_FASTPWM            0x48    //Mode 3
#define TCCR2_CS_BIST            0x0x    //Mode 3
#define TCCR2_CLK_1024    0x07   
#define TCCR2_CLK_256    0x06   
#define TCCR2_CLK_128    0x05
#define TCCR2_CLK_64    0x04    //
#define TCCR2_CLK_32    0x03
#define TCCR2_CLK_8        0x02    //    1/F =
#define TCCR2_CLK_0        0x01   
#define TCCR2_CLK_STOP    0x00   
//TIMER2 WIRD BERECHNET /z.B:OverFLow SYSCLK /  256 / TCCR2_CLK_64 =  OVL/Sec
// 1/OVLS = 1/ =
//----->

//#define TCCR1B_CLOCKSEL_CTC1         0x08    //Clear Timer/Counter  on Compare Match Timer/Counter 1
#define TCCR1B_CLOCKSEL_STOP        0x00    //Clock Select Bits
#define TCCR1B_CTC_MODE                0x08    //Clock Select Bits
#define TCCR1B_CLOCKSEL_CPU_1        0x01    //Clock Select Bits
#define TCCR1B_CLOCKSEL_CPU_8        0x02    //Clock Select Bits
#define TCCR1B_CLOCKSEL_CPU_64        0x03    //Clock Select Bits
#define TCCR1B_CLOCKSEL_CPU_256        0x04    //Clock Select Bits
#define TCCR1B_CLOCKSEL_CPU_1024    0x05    //Clock Select Bits



//INTERUPT CTRL REG //NICHT mit MCUCSR verwechseln !
#define MCUCR_LOWLEVEL_INT0        0x00   
#define MCUCR_ANYCHANGE_INT0    0x01 //=_BV(ISC01)    
#define MCUCR_FALLING_EDGE_INT0    0x02   
#define MCUCR_RISING_EDGE_INT0    0x03

#define MCUCR_LOWLEVEL_INT1        0x00   
#define MCUCR_ANYCHANGE_INT1    0x04 //=_BV(ISC10)    
#define MCUCR_FALLING_EDGE_INT1    0x08   
#define MCUCR_RISING_EDGE_INT1    0x0C

#define GATE_ANYCHANGE_INT1_MODE_MAC    (MCUCR |= MCUCR_ANYCHANGE_INT1)

#define OVERFLOW_CNT_ON_INT0_MAC    RCO_B_INT_ON_MAC
#define OVERFLOW_CNT_OFF_INT0_MAC    RCO_B_INT_OFF_MAC

#define GATE_ALL_EVENT_ON_INT1_MAC    GATE_INT1_ON_MAC
#define GATE_ALL_EVENT_OFF_INT1_MAC    GATE_INT1_OFF_MAC

//PORTB
#define MOSI_I         3//BIT3
#define MISO_0         4//BIT4
#define SCK_I          5//BIT5

//#define TCCR1B_CLOCKSEL_CTC1         0x08    //Clear Timer/Counter  on Compare Match Timer/Counter 1
#define TCCR1B_CLOCKSEL_STOP        0x00    //Clock Select Bits
#define TCCR1B_CLOCKSEL_CPU_1        0x01    //Clock Select Bits
#define TCCR1B_CLOCKSEL_CPU_8        0x02    //Clock Select Bits
#define TCCR1B_CLOCKSEL_CPU_64        0x03    //Clock Select Bits
#define TCCR1B_CLOCKSEL_CPU_256        0x04    //Clock Select Bits
#define TCCR1B_CLOCKSEL_CPU_1024    0x05    //Clock Select Bits



//EEPROM
#define EEPROM_SECTION  __attribute__ ((section (".eeprom")))
#define IEEPROM_SIZE    512    //Interne EEPROM
#define EE_DUMMYLOAD 0x5AA5 //unwahrsch. wert 0101 1010 1010 0101
//If using 8 block by 512 max = 64 Byte/block
//#define IEEPROM_SECTIONSIZE    64   //by 8 Section




//INTERRUPT
#define INTx_INPORT    PIND
//#define INT1_MASK    0x08  //PD3
//#define INT0_MASK    0x04  //PD2
#define INT0_PIN_NR    PD2
#define INT1_PIN_NR    PD3


//PORTB
#define TWI_DIRREG        DDRC
#define TWI_OUT_PORT    PORTC
#define TWI_IN_PORT        PINC
#define TWI_SDA            PC4        //PC4    OUT
#define TWI_SCL            PC5        //PC5    IN

/*
#define Clr_TWI_SDA_MAC         TWI_OUT_PORT &= ~PC_SDA_BIT;     
#define Set_TWI_SDA_MAC         TWI_OUT_PORT |= PC_SDA_BIT;     
#define TWI_SCL_IS_HIGH        (TWI_IN_PORT & PC_SCL_BIT )
#define TWI_SCL_IS_LOW        (!(TWI_IN_PORT & PC_SCL_BIT))
*/


//PORTD TX/RX ERST MAL FÜR  FLAGS
#define PD0_RX_BIT    0x01    //PIN2
#define PD1_TX_BIT    0x02    //PIN3


//========================================================================

//TIMERS
//TIMER2  = is 61 miliseconds Timer ~approx.
// 16MhZ / 1024 / 256  = 61,03515625 Hz
// T= 1/f = 0.016384 ms / Interrupt
#define TIMER2_INT_FREQUENCY    61.03515625
#define TIMER2_INTPERIODE        0.016384 //1/TIMER2_INT_FREQUENCY BY EVERY OVERFLOW = 1 Second!
#define ONE_SECOND_TICKS        61    //1/ TIMER2_INTPERIODE
#define LONG_10DELAY_TICKS        610    //1/ TIMER2_INTPERIODE
#define SM_AFTERSTOPDELAY_TICKS    2    //~16ms 1=TIMER2_INTPERIODE,

//-----------------------

//MASKENBITS


//FLAG MEANING USED VOR INTERRUPT
/*
BIT 7
BIT 6
BIT 5
BIT 4
BIT 3
BIT 2
BIT 1
BIT 0 = INT0 = 0x01
*/

#define WDTO_2S   7 //WatchDog
//SOFTWARE USED DEFINES


#define ASC_CR    13
#define ASC_LF    10

//COMMAND
#define DELIMITER        ','
#define DELIMITERSTR    ","


//delay.h 8-bit count,
//EIn Aufruf von _delay_loop_2 = 4 Cyclen lan = 0.00000025 = 0.250 NanoSecunden
/*
#define OneCycletime    0.0000000625  // 1 / F_CPU
#define DELAYCYCLE_3    0.0000001875 //375ns für eine Pause //CPU_CYCLE_TIME *3 für 8 Bit
#define DELAYCYCLE_4     0.00000025 //500ns für eine!!! Pause= _delay_loop_2(1); //CPU_CYCLE_TIME *4 für 16Bit
// 500nS sind 8 * OneCycletime
//1ms= 16000 * OneCycletime
#define DELAY_1NS        4    //4 * 4 Cycles
#define DELAY_1000NS    4000 //()
*/

#define FLOAT_OVERFLOW_2_19 0x7FFFFUL //= liegt VOR Überlauf !!! 524287    Um es Vor!! DEM ÜBERLAUF ABZUFANGEN
#define HALF_FLOAT_OVERFLOW 0x3FFFFUL

#define BITS_PER_BYTE    8
#define PORTB_BYTEs        8
#define PORTD_BYTEs        7

//CHECK PUD = PULLUPDISSABLE in SFIOR
//8Bit PORT B    //1=OUT
//1=OUT
#define PORTB_DDRX_OUTMASK        0b00011100
#define PORTB_PRESET_PULLMASK    0x00
//7Bit PORT D    //1=OUT
// TX/RX & zusatzhardware
#define PORTD_DDRX_OUTMASK        0b00000010
#define PORTD_PRESET_PULLMASK    0x00

//TEST AND DEBUG SECTION
//USE_TOGGLE_FLAG                    0    //ToggleTEST_BIT(xx);
#ifdef USE_TOGGLE_FLAG
    #define  TESTBIT_DIRREG        DDRB
    #define  TESTBIT_PORT        PORTB
    #define TESTBIT_BIT            0x01
    #define TESTBIT_INVERT_BIT    0xFE
    #define INIT_TESTBIT_REG_MAC    (TESTBIT_DIRREG |= TESTBIT_BIT);
    #define SET_TESTBIT_MAC            (TESTBIT_PORT |= TESTBIT_BIT);
    #define CLR_TESTBIT_MAC            (TESTBIT_PORT &= TESTBIT_INVERT_BIT);
    extern void ToggleTEST_BIT(uint8_t ucCnt);
#endif

//TIMER
#define TIMSK_OCIE0A_FLAG    0x01
#define TIMSK_TOIE0_FLAG    0x02
#define TIMSK_OCIE0B_FLAG    0x04
#define TIMSK_ICIE1_FLAG    0x08
#define TIMSK_OCIE1B_FLAG    0x20
#define TIMSK_OCIE1A_FLAG    0x40
#define TIMSK_TOIE1_FLAG    0x80


#define TIMSK_T0_CLR_ALL_MASK 0b11111100
#define TIMSK_T1_CLR_ALL_MASK 0b11000011
#define TIMSK_T2_CLR_ALL_MASK 0b00111111


#define TIFR_TOV0_TIMER_OVERFLOW_FLAG    0x01
#define TIFR_OCF0_OUT_PCOMPARE_FLAG        0x02
#define TIFR_TOV1_TIMER_OVERFLOW_FLAG    0x04
#define TIFR_OCF1A_OUTP_COMPARE_A_FLAG    0x10
#define TIFR_OCF1B_OUTP_COMPARE_B_FLAG    0x08

//INTERRUPT MODE
//#define MCUCR_INT0_LOWLEVEL_CLRMASK    0xFC
#define MCUCR_INT0_LOWLEVEL        0x00
#define MCUCR_INT0_ANY_CHANGE    0x01
#define MCUCR_INT0_FALLING_EDGE    0x02
#define MCUCR_INT0_RISING_EDGE    0x03
#define MCUCR_INT0_CLEAR_MASK    0xFC

//#define MCUCR_INT1_LOWLEVEL_CLRMASK    0xF3
#define MCUCR_INT1_LOWLEVEL        0x00
#define MCUCR_INT1_ANY_CHANGE    0x04
#define MCUCR_INT1_FALLING_EDGE    0x08    //_BV(ISC11)
#define MCUCR_INT1_RISING_EDGE    0x0C
#define MCUCR_INT1_CLEAR_MASK    0xF3
 

#define GICR_INT1_FLAG    0x80
#define GICR_INT0_FLAG    0x40
#define GICR_INT2_FLAG    0x20


#define GIFR_INTF1_FLAG    0x80
#define GIFR_INTF0_FLAG    0x40
#define GIFR_INTF2_FLAG    0x20

//TIMERS
#define TCCR0_FAST_PWM    0x48    //Mode 3
#define TCCR0_OC0_MODE    0x20    //Clear ON compare Match
#define TCCR0_OC0_DISCONNECT_MODE    0x00
#define TCCR0_CLK_1024    0x05    //~61,035 PWM
#define TCCR0_CLK_256    0x04    //244,14Hz PWM
#define TCCR0_CLK_64    0x03    //976,56Hz PWM
#define TCCR0_CLK_8        0x02    //7812 Hz PWM
#define TCCR0_CLK_0        0x01    //62500 PWM
#define TCCR0_CLK_STOP_MASK    0xF8   

#define TCCR2_WGM_NORMAL    0x00
#define TCCR2_CTC_MODE        0x08 //0000 1000
#define TCCR2_COM_NORMALPORT    0x00
#define TCCR2_FASTPWM        0x48    //Mode 3
#define TCCR2_CS_BIST        0x0x    //Mode 3
#define TCCR2_CLK_0            0x01
#define TCCR2_CLK_8            0x02
#define TCCR2_CLK_32        0x03
#define TCCR2_CLK_64        0x04
#define TCCR2_CLK_128        0x05
#define TCCR2_CLK_256        0x06
#define TCCR2_CLK_1024        0x07
#define TCCR2_CLK_STOP_MASK    0xF8

//TCCR1A

#define TCCR1A_CTC_MODE            0x00    //WGM11 WGM10  = 0
#define TCCR1A_FAST_PWM_ICR1    0x02 //WGM11
#define TCCR1A_FAST_PWM_OCR1A    0x03 //WGM11 WGM10

//#define TCCR1B_CLOCKSEL_CTC1         0x08    //Clear Timer/Counter  on Compare Match Timer/Counter 1
#define TCCR1B_CLOCKSEL_STOP        0x00    //Clock Select Bits
#define TCCR1B_CTC_MODE                0x08    //Clock Select Bits
#define TCCR1B_CLOCKSEL_CPU_1        0x01    //Clock Select Bits
#define TCCR1B_CLOCKSEL_CPU_8        0x02    //Clock Select Bits
#define TCCR1B_CLOCKSEL_CPU_64        0x03    //Clock Select Bits
#define TCCR1B_CLOCKSEL_CPU_256        0x04    //Clock Select Bits
#define TCCR1B_CLOCKSEL_CPU_1024    0x05    //Clock Select Bits
#define TCCR1B_CLK_STOP_MASK        0xF8

#define TC1_USED_CLOCKS_PER_SEC        15625    //16^6 / 1024

//ADC    #define ACSR

//PRESCALER
#define ADCSRA_ADPS0    0x01
#define ADCSRA_ADPS1    0x02
#define ADCSRA_ADPS2    0x04
#define ADCSRA_ADIE        0x08
#define ADCSRA_ADIF        0x10        //INTERRRUPT FLAG
#define ADCSRA_ADFR        0x20    //FREE RUNNNG SEL
#define ADCSRA_ADSC        0x40    //START  //while (ADCSRA & _BV(ADSC) )
#define ADCSRA_ADEN        0x80    //Enable

#define  ADCSRA_PRESCALER_2        0x01
#define  ADCSRA_PRESCALER_4        0x02
#define  ADCSRA_PRESCALER_8        0x03
#define  ADCSRA_PRESCALER_16    0x04
#define  ADCSRA_PRESCALER_32    0x05
#define  ADCSRA_PRESCALER_64    0x06
#define  ADCSRA_PRESCALER_128    0x07
//WERT IN ADCW


/*
Probiere mal aus
EECR |= ( 1<<EEMPE) EEPROM WRITE
EECR |= ( 1<<EEPE) EEPROM WRITE

__enable_interrupt(); //Set gloabl int enable
__Sleep() // sleep, wait vor Int

WDT_off();
MCUCSR |= (1<<WDCE) | (1<<WDE);
WDTCR=0x00;
__enable_interrupt() //Set gloabl int enable

*/

//PWM T1 SECTION
// 16MHz / 8 / 50
#define PWM_TEILER_FUER50HZ    40000U // für 16MHZ

#define PWM1_DEFAULT_VAL 3000
#define PWM2_DEFAULT_VAL 3000

#define PWM_ENABLE_PORT    PORTB
#define PWM_ENABLE_BIT    0x04
#define PWM_ENABLE()    (PWM_ENABLE_PORT |= PWM_ENABLE_BIT)
#define PWM_DISABLE()    (PWM_ENABLE_PORT &= ~PWM_ENABLE_BIT)
#define PWM_ONSTATE_READ()    (PWM_ENABLE_PORT & pwm1,35BIT)


#define    MODE_PREFIX_ENABLE    0x01
#define    MODE_TX_TRAFFIC        0x02
#define    MODE_SERVOS_ACTIVE    0x04
#define    MODE_SERVOS_POWERFALLBACK    0x08
//static uint8_t    gu8Mode;

//TIMER1 SEITE 84pdf
//Presacle 0,8,64.256.1024
/*
8MHZ/ Prescale8= 1^6
gewünscht 50Hz = 20000 Couterlimit
1^6/50 = 20000
pwmm 1 udn 2 also von 0bis 20000

Fix TOP VALUES = 20000
*/

#endif  //MAIN_HEADER