tarou yamada / nucleo_rotary_encoder

Dependents:   serial_connected_mcu_nucleo rotary_encoder_mbed serial_connected_mcu_nucleo omuni_speed_pid ... more

Fork of rotary_encoder by tarou yamada

Files at this revision

API Documentation at this revision

Comitter:
inst
Date:
Sat Feb 06 14:24:56 2016 +0000
Child:
1:0b315dd1bbbf
Commit message:
many classes

Changed in this revision

rotary_encoder.cpp Show annotated file Show diff for this revision Revisions of this file
rotary_encoder.hpp Show annotated file Show diff for this revision Revisions of this file
rotary_encoder_a_phase.hpp Show annotated file Show diff for this revision Revisions of this file
rotary_encoder_ab_phase.hpp Show annotated file Show diff for this revision Revisions of this file
rotary_encoder_abz_phase/rotary_encoder_abz_phase.cpp Show annotated file Show diff for this revision Revisions of this file
rotary_encoder_abz_phase/rotary_encoder_abz_phase.hpp Show annotated file Show diff for this revision Revisions of this file
rotary_encoder_base/EncoderMspInitF4.cpp Show annotated file Show diff for this revision Revisions of this file
rotary_encoder_base/rotary_encoder_base.cpp Show annotated file Show diff for this revision Revisions of this file
rotary_encoder_base/rotary_encoder_base.hpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rotary_encoder.cpp	Sat Feb 06 14:24:56 2016 +0000
@@ -0,0 +1,12 @@
+#include "mbed.h"
+#include "rotary_encoder.hpp"
+
+const size_t rotary_encoder::max_counts_ = 0xFFFF;
+
+rotary_encoder::rotary_encoder(size_t resolution) :
+        resolution_(resolution) {}
+rotary_encoder::~rotary_encoder() {}
+
+float rotary_encoder::get_revol_num() const {
+    return static_cast<float>(get_counts()) / resolution_;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rotary_encoder.hpp	Sat Feb 06 14:24:56 2016 +0000
@@ -0,0 +1,23 @@
+#ifndef INCLUDED_ROTARY_ENCODER_H
+#define INCLUDED_ROTARY_ENCODER_H
+
+#include "mbed.h"
+
+class rotary_encoder {
+public:
+    rotary_encoder(size_t resolution);
+    virtual ~rotary_encoder() = 0;
+    
+    virtual int32_t get_counts() const = 0;
+    float get_revol_num() const;
+    
+    virtual void reset() = 0;
+    virtual void start() = 0;
+    virtual void stop() = 0;
+
+protected:
+    static const size_t max_counts_;
+    const size_t resolution_;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rotary_encoder_a_phase.hpp	Sat Feb 06 14:24:56 2016 +0000
@@ -0,0 +1,32 @@
+#ifndef INCLUDED_ROTARY_ENCODER_A_PHASE_H
+#define INCLUDED_ROTARY_ENCODER_A_PHASE_H
+
+#include "rotary_encoder_base.hpp"
+#include "mbed.h"
+
+/*
+ * TIM1_CH1: AF1 @ PA_8
+ * TIM1_CH2: AF1 @ PA_9
+ *
+ * TIM2_CH1: AF1 @ PA_0
+ * TIM2_CH2: AF1 @ PA_1
+ *
+ * TIM3_CH1: AF2 @ PB_4
+ * TIM3_CH2: AF2 @ PB_5
+ *
+ * TIM4_CH1: AF2 @ PB_6, PD_12
+ * TIM4_CH2: AF2 @ PB_7, PD_13
+ *
+ * TIM5_CH1: AF2 @ PA_0*    *TIM5 used by mbed system ticker so unavailable
+ * TIM5_CH2: AF2 @ PA_1*
+ *
+ */
+
+class rotary_encoder_a_phase : public rotary_encoder_base {
+public:
+    rotary_encoder_a_phase(TIM_TypeDef* timer_type, size_t resolution) :
+        rotary_encoder_base(timer_type, TIM_ENCODERMODE_TI1, resolution) {}
+    virtual ~rotary_encoder_a_phase() {}
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rotary_encoder_ab_phase.hpp	Sat Feb 06 14:24:56 2016 +0000
@@ -0,0 +1,32 @@
+#ifndef INCLUDED_ROTARY_ENCODER_A_PHASE_H
+#define INCLUDED_ROTARY_ENCODER_A_PHASE_H
+
+#include "rotary_encoder_base.hpp"
+#include "mbed.h"
+
+/*
+ * TIM1_CH1: AF1 @ PA_8
+ * TIM1_CH2: AF1 @ PA_9
+ *
+ * TIM2_CH1: AF1 @ PA_0
+ * TIM2_CH2: AF1 @ PA_1
+ *
+ * TIM3_CH1: AF2 @ PB_4
+ * TIM3_CH2: AF2 @ PB_5
+ *
+ * TIM4_CH1: AF2 @ PB_6, PD_12
+ * TIM4_CH2: AF2 @ PB_7, PD_13
+ *
+ * TIM5_CH1: AF2 @ PA_0*    *TIM5 used by mbed system ticker so unavailable
+ * TIM5_CH2: AF2 @ PA_1*
+ *
+ */
+
+class rotary_encoder_ab_phase : public rotary_encoder_base {
+public:
+    rotary_encoder_ab_phase(TIM_TypeDef* timer_type, size_t resolution) :
+        rotary_encoder_base(timer_type, TIM_ENCODERMODE_TI12, resolution) {}
+    virtual ~rotary_encoder_ab_phase() {}
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rotary_encoder_abz_phase/rotary_encoder_abz_phase.cpp	Sat Feb 06 14:24:56 2016 +0000
@@ -0,0 +1,38 @@
+#include "mbed.h"
+#include "rotary_encoder_abz_phase.hpp"
+#include "rotary_encoder_base.hpp"
+
+rotary_encoder_abz_phase::rotary_encoder_abz_phase(TIM_TypeDef* timer_type, PinName z_pin, size_t resolution) :
+        rotary_encoder_base(timer_type, TIM_ENCODERMODE_TI12, resolution),
+        z_phase_intr_(z_pin),
+        counts_in_prev_intr_(0) {
+    z_phase_intr_.fall(this, &rotary_encoder_abz_phase::intr_z_phase_first);
+}
+
+int32_t rotary_encoder_abz_phase::get_counts() const {
+    int32_t counts = timer_handler_->Instance->CNT;
+    
+    if (counts > (max_counts_ >> 1)) {
+        return counts - max_counts_;
+    }
+    return  counts;
+}
+
+void rotary_encoder_abz_phase::intr_z_phase_first() {
+    counts_in_prev_intr_ = timer_handler_->Instance->CNT;
+    z_phase_intr_.fall(this, &rotary_encoder_abz_phase::intr_z_phase);
+}
+
+void rotary_encoder_abz_phase::intr_z_phase() {
+    uint32_t counts = timer_handler_->Instance->CNT;
+    // Z相の割り込みが入る時は、前回とのカウントの差は分解能で割り切れるはず
+    int64_t error = (counts - counts_in_prev_intr_) % resolution_;
+    timer_handler_->Instance->CNT -= error;
+    
+    counts_in_prev_intr_ = counts;
+}
+
+void rotary_encoder_abz_phase::reset() {
+    counts_in_prev_intr_ = 0;
+    timer_handler_->Instance->CNT = 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rotary_encoder_abz_phase/rotary_encoder_abz_phase.hpp	Sat Feb 06 14:24:56 2016 +0000
@@ -0,0 +1,42 @@
+#ifndef INCLUDED_ROTARY_ENCODER_A_PHASE_H
+#define INCLUDED_ROTARY_ENCODER_A_PHASE_H
+
+#include "rotary_encoder_base.hpp"
+#include "mbed.h"
+
+/*
+ * TIM1_CH1: AF1 @ PA_8
+ * TIM1_CH2: AF1 @ PA_9
+ *
+ * TIM2_CH1: AF1 @ PA_0
+ * TIM2_CH2: AF1 @ PA_1
+ *
+ * TIM3_CH1: AF2 @ PB_4
+ * TIM3_CH2: AF2 @ PB_5
+ *
+ * TIM4_CH1: AF2 @ PB_6, PD_12
+ * TIM4_CH2: AF2 @ PB_7, PD_13
+ *
+ * TIM5_CH1: AF2 @ PA_0*    *TIM5 used by mbed system ticker so unavailable
+ * TIM5_CH2: AF2 @ PA_1*
+ *
+ */
+
+class rotary_encoder_abz_phase : public rotary_encoder_base {
+public:
+    rotary_encoder_abz_phase(TIM_TypeDef* timer_type, PinName z_pin, size_t resolution);
+    virtual ~rotary_encoder_abz_phase() {}
+    
+    virtual int32_t get_counts() const;
+    
+    virtual void reset();
+    
+private:
+    void intr_z_phase_first();
+    void intr_z_phase();
+    
+    InterruptIn z_phase_intr_;
+    uint32_t counts_in_prev_intr_;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rotary_encoder_base/EncoderMspInitF4.cpp	Sat Feb 06 14:24:56 2016 +0000
@@ -0,0 +1,76 @@
+#include "mbed.h"
+/*
+ * HAL_TIM_Encoder_MspInit()
+ * Overrides the __weak function stub in stm32f4xx_hal_tim.h
+ *
+ * Edit the below for your preferred pin wiring & pullup/down
+ * I have encoder common at 3V3, using GPIO_PULLDOWN on inputs.
+ * Encoder A&B outputs connected directly to GPIOs.
+ *
+ * www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/DM00102166.pdf
+ * www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/DM00141306.pdf
+ *
+ * TIM1_CH1: AF1 @ PA_8, PE_9 
+ * TIM1_CH2: AF1 @ PA_9, PE_11 
+ *
+ * TIM2_CH1: AF1 @ PA_0, PA_5, PA_15, PB_8*     *F446 only
+ * TIM2_CH2: AF1 @ PA_1, PB_3, PB_9*            *F446 only
+ *
+ * TIM3_CH1: AF2 @ PA_6, PB_4, PC_6
+ * TIM3_CH2: AF2 @ PA_7, PB_5, PC_7
+ *
+ * TIM4_CH1: AF2 @ PB_6, PD_12
+ * TIM4_CH2: AF2 @ PB_7, PD_13
+ *
+ * TIM5_CH1: AF2 @ PA_0*    *TIM5 used by mbed system ticker so unavailable
+ * TIM5_CH2: AF2 @ PA_1*
+ *
+ */
+
+#ifdef TARGET_STM32F4
+void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim)
+{
+    GPIO_InitTypeDef GPIO_InitStruct;
+
+    if (htim->Instance == TIM1) { //PA8 PA9 = Nucleo D7 D8
+        __TIM1_CLK_ENABLE();
+        __GPIOA_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
+        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+    }
+    else if (htim->Instance == TIM2) { //PA0 PA1 = Nucleo A0 A1
+        __TIM2_CLK_ENABLE();
+        __GPIOA_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
+        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+    }
+    else if (htim->Instance == TIM3) { //PB4 PB5 = Nucleo D5 D4
+        __TIM3_CLK_ENABLE();
+        __GPIOB_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_4 | GPIO_PIN_5;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
+        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+    }
+    else if (htim->Instance == TIM4) { // PB6 PB7 = Nucleo D10 MORPHO_PB7
+        __TIM4_CLK_ENABLE();
+        __GPIOB_CLK_ENABLE();
+        GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Alternate = GPIO_AF2_TIM4;
+        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+    }
+}
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rotary_encoder_base/rotary_encoder_base.cpp	Sat Feb 06 14:24:56 2016 +0000
@@ -0,0 +1,57 @@
+#include "rotary_encoder_base.hpp"
+#include "rotary_encoder.hpp"
+
+rotary_encoder_base::rotary_encoder_base(TIM_TypeDef* timer_type,
+                                        uint32_t encoder_mode,
+                                        size_t resolution) : rotary_encoder(resolution) {
+    TIM_Encoder_InitTypeDef encoder;
+    timer_handler_ = new TIM_HandleTypeDef;
+    
+    timer_handler_->Instance              = timer_type;
+    timer_handler_->Init.Period           = max_counts_;
+    timer_handler_->Init.CounterMode      = TIM_COUNTERMODE_UP;
+    timer_handler_->Init.Prescaler        = 0;
+    timer_handler_->Init.ClockDivision    = TIM_CLOCKDIVISION_DIV1;
+
+    encoder.EncoderMode = encoder_mode;
+
+    encoder.IC1Filter       = 0x0F;
+    encoder.IC1Polarity     = TIM_INPUTCHANNELPOLARITY_RISING;
+    encoder.IC1Prescaler    = TIM_ICPSC_DIV4;
+    encoder.IC1Selection    = TIM_ICSELECTION_DIRECTTI;
+
+    encoder.IC2Filter       = 0x0F;
+    encoder.IC2Polarity     = TIM_INPUTCHANNELPOLARITY_FALLING;
+    encoder.IC2Prescaler    = TIM_ICPSC_DIV4;
+    encoder.IC2Selection    = TIM_ICSELECTION_DIRECTTI;
+
+    if (HAL_TIM_Encoder_Init(timer_handler_, &encoder) != HAL_OK) {
+        error("couldn't init encoder\r\n");
+    }
+}
+
+int32_t rotary_encoder_base::get_counts() const {
+    int32_t counts = timer_handler_->Instance->CNT;
+    
+    if (counts > (max_counts_ >> 1)) {
+        return counts - max_counts_;
+    }
+    
+    return  counts;
+}
+
+void rotary_encoder_base::reset() {
+    timer_handler_->Instance->CNT = 0;
+}
+
+void rotary_encoder_base::start() {
+    if(HAL_TIM_Encoder_Start(timer_handler_, TIM_CHANNEL_1) != HAL_OK) {
+        error("couldn't start encoder\r\n");
+    }
+}
+
+void rotary_encoder_base::stop() {
+    if(HAL_TIM_Encoder_Stop(timer_handler_, TIM_CHANNEL_1) != HAL_OK) {
+        error("couldn't start encoder\r\n");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rotary_encoder_base/rotary_encoder_base.hpp	Sat Feb 06 14:24:56 2016 +0000
@@ -0,0 +1,23 @@
+#ifndef INCLUDED_ROTARY_ENCODER_BASE_H
+#define INCLUDED_ROTARY_ENCODER_BASE_H
+
+#include "rotary_encoder.hpp"
+
+class rotary_encoder_base : public rotary_encoder {
+public:
+    rotary_encoder_base(TIM_TypeDef* timer_type,
+                        uint32_t encoder_mode,
+                        size_t resolution);
+    virtual ~rotary_encoder_base() {}
+    
+    virtual int32_t get_counts() const;
+    
+    virtual void reset();
+    virtual void start();
+    virtual void stop();
+    
+protected:
+    TIM_HandleTypeDef* timer_handler_;
+};
+
+#endif