#include "encoders.h"

namespace enc1
{
    int32_t pos = 0;
    
    void Init()
    {
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);  //Periph clocking
        
        GPIO_InitTypeDef param; //port C configuration
        param.GPIO_Mode = GPIO_Mode_IN;
        param.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
        param.GPIO_PuPd = GPIO_PuPd_NOPULL;
        param.GPIO_OType = GPIO_OType_PP;
        param.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_Init(GPIOC, &param);
        
        __disable_irq(); //disable interrupts
        
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
        
        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource4); //external interrupt selection
        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource5);
        
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //set interrupt priority
        
        EXTI_InitTypeDef EXTI_InitStruct;  //exti 4 , 5 configuration
        EXTI_InitStruct.EXTI_Line = EXTI_Line4 | EXTI_Line5;
        EXTI_InitStruct.EXTI_LineCmd = ENABLE;
        EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
        EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising; //waiting rising edge
        EXTI_Init(&EXTI_InitStruct);
        
        NVIC_InitTypeDef NVIC_InitStructure; //interrupt configuration
        NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 8;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
        
        NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 9;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
        
        __enable_irq(); //enable interrupts
    }
    
    float deg()
    {
        return enc1::pos * 2 / CNT_TO_DEG;
    }
}

namespace enc2
{
    int32_t pos = 0;
    
    void Init()
    {
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);  //Periph clocking
        
        GPIO_InitTypeDef param; //port C configuration
        param.GPIO_Mode = GPIO_Mode_IN;
        param.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
        param.GPIO_PuPd = GPIO_PuPd_NOPULL;
        param.GPIO_OType = GPIO_OType_PP;
        param.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_Init(GPIOC, &param);
        
        __disable_irq(); //disable interrupts
        
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
        
        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource6); //external interrupt selection
        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource7);
        
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //set interrupt priority
        
        EXTI_InitTypeDef EXTI_InitStruct;   //exti 6 , 7 configuration
        EXTI_InitStruct.EXTI_Line = EXTI_Line6 | EXTI_Line7;
        EXTI_InitStruct.EXTI_LineCmd = ENABLE;
        EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
        EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising; //waiting rising edge
        EXTI_Init(&EXTI_InitStruct);
        
        NVIC_InitTypeDef NVIC_InitStructure; //interrupt configuration
        NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 9;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
        
        __enable_irq(); //enable interrupts
    }
    
    float deg()
    {
        return enc2::pos * 2 / CNT_TO_DEG;
    }
}

namespace enc3
{
    int32_t pos = 0;
    
    void Init()
    {
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);  //Periph clocking
        
        GPIO_InitTypeDef param; //port C configuration
        param.GPIO_Mode = GPIO_Mode_IN;
        param.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
        param.GPIO_PuPd = GPIO_PuPd_NOPULL;
        param.GPIO_OType = GPIO_OType_PP;
        param.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_Init(GPIOC, &param);
        
        __disable_irq(); //disable interrupts
        
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
        
        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource0); //external interrupt selection
        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource1);
        
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //set interrupt priority
        
        EXTI_InitTypeDef EXTI_InitStruct;   //exti 0 , 1 configuration
        EXTI_InitStruct.EXTI_Line = EXTI_Line0 | EXTI_Line1;
        EXTI_InitStruct.EXTI_LineCmd = ENABLE;
        EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
        EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising; //waiting rising edge
        EXTI_Init(&EXTI_InitStruct);
        
        NVIC_InitTypeDef NVIC_InitStructure; //interrupt configuration
        NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 4;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
        
        NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 5;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
        
        __enable_irq(); //enable interrupts
    }
    
    float deg()
    {
        return enc3::pos * 2 / CNT_TO_DEG;
    }
}

namespace enc4
{
    int32_t pos = 0;
    
    void Init()
    {
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);  //Periph clocking
        
        GPIO_InitTypeDef param; //port C configuration
        param.GPIO_Mode = GPIO_Mode_IN;
        param.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
        param.GPIO_PuPd = GPIO_PuPd_NOPULL;
        param.GPIO_OType = GPIO_OType_PP;
        param.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_Init(GPIOC, &param);
        
        __disable_irq(); //disable interrupts
        
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
        
        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource2); //external interrupt selection
        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource3);
        
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //set interrupt priority
        
        EXTI_InitTypeDef EXTI_InitStruct;   //exti 2 , 3 configuration
        EXTI_InitStruct.EXTI_Line = EXTI_Line2 | EXTI_Line3;
        EXTI_InitStruct.EXTI_LineCmd = ENABLE;
        EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
        EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising; //waiting rising edge
        EXTI_Init(&EXTI_InitStruct);
        
        NVIC_InitTypeDef NVIC_InitStructure; //interrupt configuration
        NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 6;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
        
        NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 7;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
        
        __enable_irq(); //enable interrupts
    }
    
    float deg()
    {
        return enc4::pos * 2 / CNT_TO_DEG;
    }
}
