#include "STM32Encoder.h"

STM32Encoder::STM32Encoder (TIM_TypeDef *Instance,PinName pin_A, PinName pin_B, unsigned int prescaler, unsigned int pulsePerRevolution) {
	

	_ppr = pulsePerRevolution;

	_prescaler = prescaler;



	pinmap_pinout(pin_A, PinMap_PWM);

	pinmap_pinout(pin_B, PinMap_PWM);

	

	

	hTimEncoder.Instance = Instance;

	hTimEncoder.Init.Prescaler = prescaler;

	hTimEncoder.Init.CounterMode = TIM_COUNTERMODE_UP;

	hTimEncoder.Init.Period = pulsePerRevolution;

	hTimEncoder.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

	

	hEncoder.EncoderMode = TIM_ENCODERMODE_TI12;

	hEncoder.IC1Polarity = TIM_ICPOLARITY_RISING;

	hEncoder.IC1Selection = TIM_ICSELECTION_DIRECTTI;

	hEncoder.IC1Prescaler = TIM_ICPSC_DIV1;

	hEncoder.IC1Filter = 0;

	hEncoder.IC2Polarity = TIM_ICPOLARITY_RISING;

	hEncoder.IC2Selection = TIM_ICSELECTION_DIRECTTI;

	hEncoder.IC2Prescaler = TIM_ICPSC_DIV1;

	hEncoder.IC2Filter = 0;

	

	sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

	sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

	
};





void STM32Encoder::begin()

{

	//使能TIM时钟

	enableTimerClock(&hTimEncoder);

	

	HAL_TIM_Encoder_Init(&hTimEncoder,&hEncoder);

	

	HAL_TIMEx_MasterConfigSynchronization(&hTimEncoder, &sMasterConfig);



	HAL_TIM_Encoder_Start(&hTimEncoder,TIM_CHANNEL_ALL);

}



void STM32Encoder::stop()

{

	HAL_TIM_Encoder_Stop(&hTimEncoder, TIM_CHANNEL_ALL);

}

float STM32Encoder::getAngle(unsigned char base){

	const float angle_base[3] = {360.0f, 6.2831f, 400.0f};

	if (base <= 2){
		return ((value()/(float)_ppr) * angle_base[base]);
	} else {
		return -900.0; //ridiculous, isn't it? 
	}
		
}

unsigned char STM32Encoder::getDirection(){

	

	char x = 0;

	if(__HAL_TIM_DIRECTION_STATUS(&hTimEncoder)==0){

		x = 1;

	}else{

		x = 0;

	}

	return x;
}

void STM32Encoder::Polarity(unsigned char pol) {

	

	if(pol == 1){

		hEncoder.IC1Polarity = TIM_ICPOLARITY_RISING;

		hEncoder.IC2Polarity = TIM_ICPOLARITY_RISING;

	}else if(pol == 2){

		hEncoder.IC1Polarity = TIM_ICPOLARITY_FALLING;

		hEncoder.IC2Polarity = TIM_ICPOLARITY_FALLING;

	}else if(pol == 3){

		hEncoder.IC1Polarity = TIM_ICPOLARITY_BOTHEDGE;

		hEncoder.IC2Polarity = TIM_ICPOLARITY_BOTHEDGE;

	}
}

void STM32Encoder::reset(){

	

	__HAL_TIM_SetCounter(&hTimEncoder,0);
};

unsigned int STM32Encoder::value() {

	

	return __HAL_TIM_GetCounter(&hTimEncoder);
};
	
void STM32Encoder::setPrescaler(unsigned int prescale){

	

	hTimEncoder.Init.Prescaler = prescale;

	

	_prescaler = prescale;
};

unsigned int STM32Encoder::getPrescaler(){


	

	return _prescaler;
};

void STM32Encoder::setPPR(unsigned int pulserPerRevolution){
	_ppr = pulserPerRevolution; 

	

	hTimEncoder.Init.Period = pulserPerRevolution;
};

unsigned int STM32Encoder::getPPR(){
	return _ppr;
};

//void STM32Encoder::attachInterrupt(void (*handler)(HardwareTimer *)) {
//
//	//attach interrupt
//
//}
//
//void STM32Encoder::detachInterrupt() {
//
//}

void STM32Encoder::setFilter(unsigned char val) {

	val = val & 0xF; //clear the upper nibble.


	hEncoder.IC1Filter = val;

	hEncoder.IC2Filter = val;
}
