#include <avr/io.h>

    /*------------------------------------------------------------------------------
        BITS MACROS
    ..............................................................................*/

    //bit struct
    struct sbits {
      uint8_t b0:1;uint8_t b1:1;uint8_t b2:1;uint8_t b3:1;
      uint8_t b4:1;uint8_t b5:1;uint8_t b6:1;uint8_t b7:1;
    };

    //port/pin/ddr bit macros
    #define BITIO(reg,letter,pin)   ((*(volatile struct sbits*)&reg##letter).b##pin)
    #define DDR_OUT                 1
    #define DDR_IN                  0

    //io register bit macros
    #define BITREG_(reg,bit)        ((*(volatile struct sbits*)&reg).b##bit)
    #define BITREG(reg,bit)         BITREG_(reg,bit) //expand bit

    //set/clear/load/toggle multiple bits
    //if more than 8 bit parameters passed
    //will get-> "warning: left shift count is negative"
    //(but will not 'corrupt' previous values)
    //limit is 8 bits, but this could be extended
    #define BITS8(arg,bits...)      ((arg!=-1)?0<<-1:0)
    #define BITS7(arg,bits...)      ((arg>=0)?(1<<(arg)):0)|BITS8(bits)
    #define BITS6(arg,bits...)      ((arg>=0)?(1<<(arg)):0)|BITS7(bits,-1)
    #define BITS5(arg,bits...)      ((arg>=0)?(1<<(arg)):0)|BITS6(bits,-1)
    #define BITS4(arg,bits...)      ((arg>=0)?(1<<(arg)):0)|BITS5(bits,-1)
    #define BITS3(arg,bits...)      ((arg>=0)?(1<<(arg)):0)|BITS4(bits,-1)
    #define BITS2(arg,bits...)      ((arg>=0)?(1<<(arg)):0)|BITS3(bits,-1)
    #define BITS1(arg,bits...)      ((arg>=0)?(1<<(arg)):0)|BITS2(bits,-1)
    #define BITS0(arg,bits...)      ((arg>=0)?(1<<(arg)):0)|BITS1(bits,-1)

    #define BITS_MASK(bits...)      (BITS0(bits,-1))
    #define BITS_SET(var,bits...)   (var |=  (BITS_MASK(bits)))
    #define BITS_CLEAR(var,bits...) (var &= ~(BITS_MASK(bits)))
    #define BITS_LOAD(var,bits...)  (var =   (BITS_MASK(bits)))
    #define BITS_TOGGLE(var,bits...)(var ^=  (BITS_MASK(bits)))


    /*.............................................................................

        BITS MACROS END
    ------------------------------------------------------------------------------*/

    //examples
    //mega164p
    int main(){

        //define device to port letter,pin number
        #define ioLED4(reg) BITIO(reg,B,0)
        #define ioSW1(reg) BITIO(reg,B,2)

        //then use with (DDR) or (PORT) or (PIN)
        ioLED4(DDR)=DDR_OUT;    //output
        ioLED4(PORT)=0;         //off
        ioSW1(DDR)=DDR_IN;      //input
        ioSW1(PORT)=1;          //pull-up on

        if(ioSW1(PIN)==0){      //if sw pushed
            ioLED4(PORT)=1;     //turn on led
        }

        //clear WDRF reset flag
        BITREG(MCUSR,WDRF)=0;

        //or define reg bit WDRF
        #define bWDRF BITREG(MCUSR,WDRF)
        bWDRF=0;

        //to clear a 'normal' flag
        //TIFR0=(1<<TOV0)
        BITS_LOAD(TIFR0,TOV0);

        //TCCR0B=(1<<CS00)|(1<<CS01);
        BITS_LOAD(TCCR0B,CS00,CS01);

        //UCSR0B|=(1<<RXEN0)|(1<<TXEN0);
        BITS_SET(UCSR0B,RXEN0,TXEN0);

        //UCSR0B&=~(1<<RXEN0)|(1<<TXEN0);
        BITS_CLEAR(UCSR0B,RXEN0,TXEN0);

        //get rx error flags
        volatile uint8_t temp;
        temp=UCSR0A&BITS_MASK(FE0,DOR0,UPE0);

    }