#ifndef __BSP_WRAPPER_H__
#define __BSP_WRAPPER_H__

#define BIT(x)        ((uint32_t)((uint32_t)0x01U<<(x)))
#define BITS(start, end)             ((0xFFFFFFFFUL << (start)) & (0xFFFFFFFFUL >> (31U - (uint32_t)(end))))

#define GPIO_MODE_AF_PP         GPIO_Mode_AF_PP
#define GPIO_MODE_AIN           GPIO_Mode_AIN
#define GPIO_MODE_IN_FLOATING   GPIO_Mode_IN_FLOATING
#define GPIO_MODE_OUT_PP        GPIO_Mode_Out_PP
#define GPIO_OSPEED_50MHZ       GPIO_Speed_50MHz
#define GPIO_MODE_IPU           GPIO_Mode_IPU

#define RCU_GPIOA               RCC_APB2_PERIPH_GPIOA
#define RCU_GPIOB               RCC_APB2_PERIPH_GPIOB
#define RCU_GPIOC               RCC_APB2_PERIPH_GPIOC
#define RCU_GPIOD               RCC_APB2_PERIPH_GPIOD
#define RCU_AF                  RCC_APB2_PERIPH_AFIO
#define RCU_TIMER5              RCC_APB1_PERIPH_TIM5
#define RCU_TIMER1              RCC_APB2_PERIPH_TIM1
#define RCU_TIMER7				RCC_APB1_PERIPH_TIM7
#define RCU_TIMER3				RCC_APB1_PERIPH_TIM3
#define RCU_TIMER4				RCC_APB1_PERIPH_TIM4
#define RCU_TIMER8              RCC_APB2_PERIPH_TIM8
#define RCU_DMA1				RCC_AHB_PERIPH_DMA1
#define RCU_ADC1				RCC_AHB_PERIPH_ADC1
#define RCU_ADC2				RCC_AHB_PERIPH_ADC2
#define RCU_CAN0                RCC_APB1_PERIPH_CAN1

#define SET Bit_SET
#define RESET Bit_RESET

#define REG32(addr)                  (*(volatile uint32_t *)(uint32_t)(addr))
#define REG16(addr)                  (*(volatile uint16_t *)(uint32_t)(addr))
#define REG8(addr)                   (*(volatile uint8_t *)(uint32_t)(addr))


#define TIMER_CNT(TIMx) (TIMx->CNT)
#define TIMER_CTL0(TIMx) (TIMx->CTRL1)
#define TIMER_INTF(TIMx) (TIMx->STS)
#define TIMER_CTL0_DIR   BIT(4)              /*!< timer counter direction */
#define TIMER_CH0CV(TIMx) (TIMx->CCDAT1)
#define TIMER_CH1CV(TIMx) (TIMx->CCDAT2)
#define TIMER_CH2CV(TIMx) (TIMx->CCDAT3)
#define TIMER_CH3CV(TIMx) (TIMx->CCDAT4)
#define TIMER_CCHP(TIMx)  (TIMx->BKDT)
#define TIMER_CHCTL1(TIMx) (TIMx->CCMOD2)
#define TIMER_CHCTL2(TIMx) (TIMx->CCEN)


#define gpio_init(gpio_periph, mode, speed, pin) \
    do {\
        GPIO_InitType GPIO_InitStructure; \
        GPIO_InitStructure.Pin = pin; \
	    GPIO_InitStructure.GPIO_Speed = speed; \
	    GPIO_InitStructure.GPIO_Mode = mode; \
	    GPIO_InitPeripheral(gpio_periph, &GPIO_InitStructure); \
    }while(0);

#define gpio_input_bit_get(gpio_periph, pin)    GPIO_ReadInputDataBit(gpio_periph, pin)
#define gpio_bit_write(gpio_periph, pin, value) GPIO_WriteBit(gpio_periph, pin, value)
#define gpio_bit_reset(gpio_periph, pin)        GPIO_ResetBits(gpio_periph, pin) 
#define gpio_pin_remap_config(pin, mode)        GPIO_ConfigPinRemap(pin, mode)

#define rcu_ahb_periph_clock_enable(clk)            RCC_EnableAHBPeriphClk(clk, ENABLE)
#define rcu_ahb_periph_clock_disable(clk)           RCC_EnableAHBPeriphClk(clk, DISABLE)

#define rcu_apb1_periph_clock_enable(clk)            RCC_EnableAPB1PeriphClk(clk, ENABLE)
#define rcu_apb1_periph_clock_disable(clk)           RCC_EnableAPB1PeriphClk(clk, DISABLE)

#define rcu_apb2_periph_clock_enable(clk)            RCC_EnableAPB2PeriphClk(clk, ENABLE)
#define rcu_apb2_periph_clock_disable(clk)           RCC_EnableAPB2PeriphClk(clk, DISABLE)

#define EXTI_INTERRUPT  EXTI_Mode_Interrupt
#define EXTI_TRIG_RISING  EXTI_Trigger_Rising
#define EXTI_TRIG_BOTH  EXTI_Trigger_Rising_Falling

#define nvic_irq_enable(irq, pri, subpri) \
    do { \
        NVIC_InitType NVIC_InitStructure; \
        NVIC_InitStructure.NVIC_IRQChannel = irq; \
	    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = pri; \
	    NVIC_InitStructure.NVIC_IRQChannelSubPriority = subpri; \
	    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; \
	    NVIC_Init(&NVIC_InitStructure); \
    }while(0);

#define nvic_irq_disable(irq) \
		do { \
			NVIC_InitType NVIC_InitStructure; \
			NVIC_InitStructure.NVIC_IRQChannel = irq; \
			NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; \
			NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; \
			NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; \
			NVIC_Init(&NVIC_InitStructure); \
		}while(0);

#define gpio_exti_source_select(group, pin)   GPIO_ConfigEXTILine(group, pin)

#define exti_init(line, mode, edge)  \
    do { \
        EXTI_InitType EXTI_InitStructure; \
        EXTI_InitStructure.EXTI_Line    = line; \
        EXTI_InitStructure.EXTI_Mode    = mode; \
        EXTI_InitStructure.EXTI_Trigger = edge; \
        EXTI_InitStructure.EXTI_LineCmd = ENABLE; \
        EXTI_InitPeripheral(&EXTI_InitStructure); \
    }while(0);

#define exti_interrupt_flag_clear(flg) EXTI_ClrITPendBit(flg)
#define exti_interrupt_flag_get(flg)   EXTI_GetITStatus(flg)

#define exti_interrupt_enable(line)  \
    do { \
        EXTI_InitType EXTI_InitStructure; \
        EXTI_InitStructure.EXTI_Line    = line; \
        EXTI_InitStructure.EXTI_LineCmd = ENABLE; \
        EXTI_InitPeripheral(&EXTI_InitStructure); \
    }while(0);

#define exti_interrupt_disable(line)  \
    do { \
        EXTI_InitType EXTI_InitStructure; \
        EXTI_InitStructure.EXTI_Line    = line; \
        EXTI_InitStructure.EXTI_LineCmd = DISABLE; \
        EXTI_InitPeripheral(&EXTI_InitStructure); \
    }while(0);
#endif /* __BSP_WRAPPER_H__ 
*/
