Timer as Encoder

Added support to use HardwareTimer as an encoder input
This commit is contained in:
Bubulindo 2015-09-11 15:24:37 +01:00
parent 2e9b4f3955
commit 73f2301cad
4 changed files with 88 additions and 0 deletions

22
STM32F1/cores/maple/HardwareTimer.cpp Normal file → Executable file
View File

@ -142,6 +142,28 @@ void HardwareTimer::refresh(void) {
timer_generate_update(this->dev);
}
/* CARLOS Changes to add encoder mode.*/
//direction of movement. (to be better described).
uint8 HardwareTimer::getDirection(){
return get_direction(this->dev);
}
//set if the encoder will count edges on one, which or both channels.
void HardwareTimer::setEdgeCounting(uint32 counting) {
(dev->regs).gen->SMCR = counting;//TIMER_SMCR_SMS_ENCODER3; //choose encoder 3, counting on
}
uint8 HardwareTimer::getEdgeCounting() {
return (dev->regs).gen->SMCR;
}
//set the polarity of counting... not sure how interesting this is..
void HardwareTimer::setPolarity(){}
/* -- Deprecated predefined instances -------------------------------------- */
HardwareTimer Timer1(1);

21
STM32F1/cores/maple/HardwareTimer.h Normal file → Executable file
View File

@ -38,6 +38,10 @@
/** Timer mode. */
typedef timer_mode TimerMode;
//CARLOS
//defines for the ENCODER mode.
/**
* @brief Interface to one of the 16-bit timer peripherals.
*/
@ -205,6 +209,23 @@ public:
*/
void refresh(void);
//CARLOS.
/*
added these functions to make sense for the encoder mode.
*/
//direction of movement. (to be better described).
uint8 getDirection();
//set if the encoder will count edges on one, which or both channels.
void setEdgeCounting(uint32 counting);
uint8 getEdgeCounting(); //not sure if needed.
//set the polarity of counting... not sure how interesting this is..
void setPolarity();
//add the filtering definition for the input channel.
/* Escape hatch */
/**

38
STM32F1/cores/maple/libmaple/timer.c Normal file → Executable file
View File

@ -38,6 +38,8 @@
static void disable_channel(timer_dev *dev, uint8 channel);
static void pwm_mode(timer_dev *dev, uint8 channel);
static void output_compare_mode(timer_dev *dev, uint8 channel);
static void encoder_mode(timer_dev *dev, uint8 channel) ;//CARLOS
static inline void enable_irq(timer_dev *dev, timer_interrupt_id iid);
@ -230,6 +232,10 @@ void timer_set_mode(timer_dev *dev, uint8 channel, timer_mode mode) {
case TIMER_OUTPUT_COMPARE:
output_compare_mode(dev, channel);
break;
//added by CARLOS.
case TIMER_ENCODER:
encoder_mode(dev, channel); //find a way to pass all the needed stuff on the 8bit var
break;
}
}
@ -293,6 +299,13 @@ void timer_detach_interrupt(timer_dev *dev, uint8 interrupt) {
dev->handlers[interrupt] = NULL;
}
//CARLOS
uint8 get_direction(timer_dev *dev){
return *bb_perip(&(dev->regs).gen->CR1, TIMER_CR1_DIR_BIT);
}
/*
* Utilities
*/
@ -313,6 +326,31 @@ static void output_compare_mode(timer_dev *dev, uint8 channel) {
timer_cc_enable(dev, channel);
}
//added by CARLOS.
static void encoder_mode(timer_dev *dev, uint8 channel) {
//prescaler.
//(dev->regs).gen->PSC = 1;
//map inputs.
(dev->regs).gen->CCMR1 = TIMER_CCMR1_CC1S_INPUT_TI1 | TIMER_CCMR1_CC2S_INPUT_TI2 | TIMER_CCMR1_IC2F | TIMER_CCMR1_IC1F ;
(dev->regs).gen->SMCR = TIMER_SMCR_SMS_ENCODER3; //choose encoder 3, counting on both edges.
//polarity
//(dev->regs).gen->CCER = TIMER_CCER_CC1P; //to invert the counting, only one of the inputs should be inverted.
//set the interval used by the encoder.
//timer_set_reload(dev, 1000);
// (dev->regs).gen->CR1 |=TIMER_CR1_UDIS_BIT;
//run timer
timer_resume(dev);
}
static void enable_adv_irq(timer_dev *dev, timer_interrupt_id id);
static void enable_bas_gen_irq(timer_dev *dev);

7
STM32F1/system/libmaple/include/libmaple/timer.h Normal file → Executable file
View File

@ -569,6 +569,8 @@ typedef enum timer_mode {
/* TIMER_ONE_PULSE, TODO: In this mode, the timer can generate a single
* pulse on a GPIO pin for a specified amount of
* time. */
TIMER_ENCODER, //CARLOS Change
} timer_mode;
/** Timer channel numbers */
@ -620,6 +622,11 @@ void timer_attach_interrupt(timer_dev *dev,
voidFuncPtr handler);
void timer_detach_interrupt(timer_dev *dev, uint8 interrupt);
//CARLOS
uint8 get_direction(timer_dev *dev);
/**
* Initialize all timer devices on the chip.
*/