//!
//! @file $RCSfile: mc_drv.h,v $
//!
//! Copyright (c) 2007 Atmel.
//!
//! @brief Low Level Functions
//!
//! @version $Revision: 1.8 $
//!


#ifndef _MC_DRV_H_
#define _MC_DRV_H_

  // output configuration
  #define output_disconnected 0x01

 // #define Set_none() (TCCR1A=output_disconnected,TCCR3B=output_disconnected)
  #define Set_timer_data_register_to_zero() (TCNT0=0x00)

  // MACRO for PSC initialization
  #define PSC_ONE_RAMP (0<<PMODE01)|(0<<PMODE00)
  #define PSC_TWO_RAMP (0<<PMODE01)|(1<<PMODE00)
  #define PSC_FOUR_RAMP (1<<PMODE01)|(0<<PMODE00)
  #define PSC_CENTERED (1<<PMODE01)|(1<<PMODE00)

  #define RAMP_MODE_NUMBER PSC_CENTERED

  #define SET_PLOCK (1<<PLOCK0)
  #define RELEASE_PLOCK (0<<PLOCK0)

  #define PRESC_NODIV     (0<<PPRE01)|(0<<PPRE00)
  #define PRESC_DIV_BY_4  (0<<PPRE01)|(1<<PPRE00)
  #define PRESC_DIV_BY_16 (1<<PPRE01)|(0<<PPRE00)
  #define PRESC_DIV_BY_64 (1<<PPRE01)|(1<<PPRE00)

  #define OUTPUT_ACTIVE_HIGH (1<<POP0)
  #define OUTPUT_ACTIVE_LOW  (0<<POP0)

  #define Enable_over_current() \
    PFRC0A = (1<<PELEV0A)|(1<<PFLTE0A)|\
             (0<<PRFM0A3)|(1<<PRFM0A2)|(1<<PRFM0A1)|(1<<PRFM0A0);
  #define Disable_over_current() \
    PFRC0A = (1<<PELEV0A)|(1<<PFLTE0A)|\
             (0<<PRFM0A3)|(0<<PRFM0A2)|(0<<PRFM0A1)|(0<<PRFM0A0);

  // Comparator interruption
  #define HALL_A() (PORTE_INT0_vect)
 // #define HALL_B() (ANACOMP_1_vect)
 // #define HALL_C() (ANACOMP_2_vect)


  #define HALL_SENSOR_VALUE()   (PORTE.IN & 0x07)

  #define Clear_Port_Q1() (PORTC.OUTCLR = PIN5_bm)
  #define Clear_Port_Q3() (PORTC.OUTCLR = PIN3_bm)
  #define Clear_Port_Q5() (PORTC.OUTCLR = PIN1_bm)
  #define Clear_Port_Q2() (PORTC.OUTCLR = PIN4_bm)
  #define Clear_Port_Q4() (PORTC.OUTCLR = PIN2_bm)
  #define Clear_Port_Q6() (PORTC.OUTCLR = PIN0_bm)
  #define Set_Port_Q2()   (PORTC.OUTSET = PIN4_bm)
  #define Set_Port_Q4()   (PORTC.OUTSET = PIN2_bm)
  #define Set_Port_Q6()   (PORTC.OUTSET = PIN0_bm)

  // Six step commutation
  #define Set_none() (AWEX_SetOutputOverrideValue(AWEXC,0))

  #define Set_Q1Q4()  AWEX_SetOutputOverrideValue(AWEXC,PIN5_bm | PIN2_bm)//(AWEXC.OUTOVEN = (PIN5_bm | PIN2_bm))

  #define Set_Q1Q6() AWEX_SetOutputOverrideValue(AWEXC,PIN5_bm | PIN0_bm)//(AWEXC.OUTOVEN = (PIN5_bm | PIN0_bm))

  #define Set_Q3Q2() AWEX_SetOutputOverrideValue(AWEXC,PIN3_bm | PIN4_bm)//(AWEXC.OUTOVEN = (PIN3_bm | PIN4_bm))

  #define Set_Q3Q6() AWEX_SetOutputOverrideValue(AWEXC,PIN3_bm | PIN0_bm)//(AWEXC.OUTOVEN = (PIN3_bm | PIN0_bm))

  #define Set_Q5Q2() AWEX_SetOutputOverrideValue(AWEXC,PIN1_bm | PIN4_bm)//(AWEXC.OUTOVEN = (PIN1_bm | PIN4_bm))

  #define Set_Q5Q4() AWEX_SetOutputOverrideValue(AWEXC,PIN1_bm | PIN2_bm)//(AWEXC.OUTOVEN = (PIN1_bm | PIN2_bm))

  // Macro for LED use
  #define switch_ON_LED()   (PORTE &= ~(1<<PE2))
  #define switch_OFF_LED()  (PORTE |=  (1<<PE2))

  //EXT PORT AS OUTPUT
  #define Set_EXT1()     (PORTB |=  (1<<PB3)) // EXT1
  #define Clear_EXT1()   (PORTB &= ~(1<<PB3))
  #define Set_EXT2()     (PORTB |=  (1<<PB4)) // EXT2
  #define Clear_EXT2()   (PORTB &= ~(1<<PB4))
  #define Toggle_EXT2()  (PINB  |=  (1<<PINB4))
  #define Set_EXT3()     (PORTC |=  (1<<PC1)) // EXT3
  #define Clear_EXT3()   (PORTC &= ~(1<<PC1))
  #define Set_EXT4()     (PORTC |=  (1<<PC2)) // EXT4
  #define Clear_EXT4()   (PORTC &= ~(1<<PC2))
  #define Set_EXT5()     (PORTB |=  (1<<PB5)) // EXT5
  #define Clear_EXT5()   (PORTB &= ~(1<<PB5))
  #define Set_EXT6()     (PORTE |=  (1<<PE1)) // EXT6
  #define Clear_EXT6()   (PORTE &= ~(1<<PE1))
  #define Set_EXT7()     (PORTD |=  (1<<PD3)) // EXT7
  #define Clear_EXT7()   (PORTD &= ~(1<<PD3))
  #define Set_EXT8()     (PORTD |=  (1<<PD4)) // EXT8
  #define Clear_EXT8()   (PORTD &= ~(1<<PD4))
  #define Set_EXT9()     (PORTE |=  (1<<PE0)) // EXT9
  #define Clear_EXT9()   (PORTE &= ~(1<<PE0))
  #define Set_EXT10()     (PORTD |=  (1<<PD2)) // EXT10
  #define Clear_EXT10()   (PORTD &= ~(1<<PD2))
  //EXT PORT AS INPUT
  #define Get_EXT1()     ((PINB & (1<<PB3))>>PB3) // EXT1
  #define Get_EXT2()     ((PINB & (1<<PB4))>>PB4) // EXT2
  #define Get_EXT3()     ((PINC & (1<<PC1))>>PC1) // EXT3
  #define Get_EXT4()     ((PINC & (1<<PC2))>>PC2) // EXT4
  #define Get_EXT5()     ((PINB & (1<<PB5))>>PB5) // EXT5
  #define Get_EXT6()     ((PINE & (1<<PE1))>>PE1) // EXT6
  #define Get_EXT7()     ((PIND & (1<<PD3))>>PD3) // EXT7
  #define Get_EXT8()     ((PIND & (1<<PD4))>>PD4) // EXT8
  #define Get_EXT9()     ((PINE & (1<<PE0))>>PE0) // EXT9
  #define Get_EXT10()     ((PIND & (1<<PD2))>>PD2) // EXT10

  // ADC scheduler definitions
  #define CONV_INIT     0
  #define CONV_POT      1
  #define CONV_CURRENT  2

  #define FREE  0
  #define BUSY  1
  /**************************/
  /* prototypes declaration */
  /**************************/

  // Hardware initialization
  void mc_init_HW(void);
  void PWM_Init (unsigned int OCRnRB);

  // Phases commutation functions
  U8 mc_get_hall(void);
  void mc_duty_cycle(U8 level);
  void mc_switch_commutation(U8 position);

  // Sampling time configuration
  void mc_init_timer1(void);

  // Estimation speed
  void mc_init_timer0(void);
  void mc_estimation_speed(void);

  // ADC use for current measure and potentiometer...
  void mc_ADC_Scheduler(void);
  U8 mc_Get_Current(void);
  U8 mc_Get_Potentiometer(void);

  // Over Current Detection
  void mc_set_Over_Current(U8 Level);
  void mc_disable_during_inrush(void);
  void mc_inrush_task(void); /* manage the inrush current */

#endif
