
#include <Arduino.h>
#include <HardwareTimer.h>

#ifndef _STM32ENCODER_H_
#define _STM32ENCODER_H_

class STM32Encoder {
	private: 

	unsigned int _ppr; //pulses per revolution of the encoder. 
	unsigned int _prescaler; //timer prescaler. 
	
	TIM_HandleTypeDef hTimEncoder;

	TIM_Encoder_InitTypeDef hEncoder;

	TIM_MasterConfigTypeDef sMasterConfig;
		
	public: 
	/*
	Constructor. 
	Timer - Timer to be used. On a Maple, Timer 1 through 4
	count_mode - Counting edges on both channels or just one and if so, which. 
	prescaler - Timer prescaler value. Useful to only count positive flanks if set to two. 
	pulsePerRevolution - number of pulses per Revolution on the encoder. Used for the Angle 
	calculation, interrupt trigger and reload value on the counter. 
	*/
	STM32Encoder (TIM_TypeDef *Instance,PinName pin_A, PinName pin_B, unsigned int prescaler, unsigned int pulsePerRevolution);
	

	//added

	void begin();

	void stop();

	
	/*
	Shaft Angle calculator.
	depending on where the encoder was reset and the number of pulses per revolution set,
	This function will calculate the current angle of the shaft. 
	base - units in which to present the angle. Possible Values: DEGREES, RADIANS, GRADIANS
	*/
	float getAngle(unsigned char base); //this returns the current encoder angle based on the number of counts and PPR. 
		
	/*
	Direction indicator. 
	This gives the current direction of the encoder. 
	*/
	unsigned char getDirection();
		
	/*
	This sets the polarity of the encoder. 
	*/
	void Polarity(unsigned char pol);
		
	/*
	Reset encoder counts. 
	*/
	void reset();
	/*
	returns an unsigned int with the current counter value. 
	*/
	unsigned int value(); //sent number of counts.
		
	/*
	Sets the prescaler of the Timer
	*/
	void setPrescaler(unsigned int prescale);
		
	/*
	Gets the prescaler of the timer. 
	*/
	unsigned int getPrescaler();
		
	/*
	Changes the pulses per revolution of the encoder. 
	This goes from 0 to 65535
	*/
	void setPPR(unsigned int pulserPerRevolution);
		
	/*
	Returns the pulses per revolution
	*/
		unsigned int getPPR();
		

		//当前为block模式，非block模式中断TODO
	/*
	Attach an interrupt that is triggered every time the Timer passes through zero. 
	*/
//		void attachInterrupt(void (*handler)(HardwareTimer *));
		
	/*
	Detach the interrupt.
	*/
//		void detachInterrupt();
		
	/*
	Adjust the filter on the input channels. 
	This can take any value from 0x0 to 0xF. 
	0x0 means no filtering and 0xF the biggest filter. 
	*/
		void setFilter(unsigned char val);	
};

#endif