Skip to content

Commit 57f39f3

Browse files
Merge pull request #81 from Santynolo/dev
Implement STM32HWEncoder count setting functions and getter for handler
2 parents 17d5738 + 890740a commit 57f39f3

3 files changed

Lines changed: 70 additions & 12 deletions

File tree

src/encoders/stm32hwencoder/README.md

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Big thank you to @conroy-cheers for originally contributing this code in pull re
66

77
## Warning
88

9-
This code has not been tested much! Use at your own risk, your milage may vary.
9+
This code has not been tested much! Use at your own risk, your milage may vary.\
1010
I have tested on: STM32F401CC/TIM4-PB6,PB7
1111

1212
## Hardware setup
@@ -17,8 +17,7 @@ Not all of the timers support the encoder mode, so check the datasheet which tim
1717

1818
An excellent option can be to use the STM32CubeIDE software's pin assignment view to quickly check which pins connect to which timer.
1919

20-
Note that the index (I) pin is currently not used.
21-
20+
Right now the index pin can be any pin supporting interrupts.
2221

2322
## Software setup
2423

@@ -46,4 +45,22 @@ void setup() {
4645
encoder.init();
4746
}
4847

48+
```
49+
50+
Set the encoder angle:
51+
52+
```c++
53+
encoder.setCurrentAngle(1.28);
54+
```
55+
56+
Set the encoder count:
57+
58+
```c++
59+
encoder.setEncoderCount(693);
60+
```
61+
62+
Get the encoder timer handle:
63+
64+
```c++
65+
encoder.getEncoderTimerHandle();
4966
```

src/encoders/stm32hwencoder/STM32HWEncoder.cpp

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,30 @@ STM32HWEncoder::STM32HWEncoder(unsigned int _ppr, int pinA, int pinB, int pinI)
1515
index_found = false;
1616
}
1717

18+
// function returns encoder handle
19+
TIM_HandleTypeDef STM32HWEncoder::getEncoderTimerHandle() { return encoder_handle; }
20+
1821
/*
1922
Shaft angle calculation
2023
*/
2124
float STM32HWEncoder::getSensorAngle() {
2225
return _2PI * encoder_handle.Instance->CNT / static_cast<float>(cpr);
2326
}
27+
/*
28+
Set the current angle using CNT register
29+
*/
30+
void STM32HWEncoder::setCurrentAngle(float set_angle) {
31+
encoder_handle.Instance->CNT = set_angle * cpr / _2PI;
32+
}
33+
/*
34+
Modify encoder count directly
35+
*/
36+
void STM32HWEncoder::setEncoderCount(uint32_t ecount) {
37+
encoder_handle.Instance->CNT = ecount;
38+
}
2439

2540
// getter for index pin
26-
int STM32HWEncoder::needsSearch() { return false && !index_found; }
41+
int STM32HWEncoder::needsSearch() { return hasIndex() && !index_found; }
2742

2843
// private function used to determine if encoder has index
2944
int STM32HWEncoder::hasIndex() { return (_pinI!=NC); }
@@ -34,11 +49,13 @@ void STM32HWEncoder::init() {
3449
TIM_TypeDef *InstanceA = (TIM_TypeDef *)pinmap_peripheral(_pinA, PinMap_TIM);
3550
if (!IS_TIM_ENCODER_INTERFACE_INSTANCE(InstanceA)) {
3651
initialized = false;
52+
SIMPLEFOC_DEBUG("STM32HWEncoder pin A doesn't support encoder interface");
3753
return;
3854
}
3955
TIM_TypeDef *InstanceB = (TIM_TypeDef *)pinmap_peripheral(_pinB, PinMap_TIM);
4056
if (InstanceA != InstanceB) {
4157
initialized = false;
58+
SIMPLEFOC_DEBUG("STM32HWEncoder pin B is not in the same timer as A");
4259
return;
4360
}
4461
pinmap_pinout(_pinA, PinMap_TIM);
@@ -74,17 +91,38 @@ void STM32HWEncoder::init() {
7491

7592
if (HAL_TIM_Encoder_Init(&encoder_handle, &encoder_config) != HAL_OK) {
7693
initialized = false;
94+
SIMPLEFOC_DEBUG("Couldn't initialize timer in encoder mode!");
7795
return;
7896
}
7997

80-
// TODO on STM32G4 MCUs we can use the TIMx_ETR pin for the index, and configure how it is handled automatically by the hardware
81-
// on non-G4 MCUs we need to use an external interrupt to handle the index signal
82-
// attachInterrupt(digitalPinToInterrupt(pinNametoDigitalPin(_pinI)), [this]() {
83-
// encoder_handle.Instance->CNT = 0; // reset counter
84-
// index_found = true;
85-
// // detach interrupt
86-
// detachInterrupt(digitalPinToInterrupt(pinNametoDigitalPin(_pinI)));
87-
// }, index_polarity);
98+
// TODO: figure out way to check if Index pin is specifically ETR line
99+
//if(IS_TIM_ETR_INSTANCE())
100+
101+
// Encoder index configuration
102+
//TIMEx_EncoderIndexConfigTypeDef encoder_indexconfig = {0};
103+
//encoder_indexconfig.Polarity = TIM_ENCODERINDEX_POLARITY_NONINVERTED;
104+
//encoder_indexconfig.Prescaler = TIM_ENCODERINDEX_PRESCALER_DIV1;
105+
//encoder_indexconfig.Filter = 0;
106+
//encoder_indexconfig.FirstIndexEnable = ENABLE;
107+
//encoder_indexconfig.Position = TIM_ENCODERINDEX_POSITION_00;
108+
//encoder_indexconfig.Direction = TIM_ENCODERINDEX_DIRECTION_UP_DOWN; // Double check this is ok
109+
//if (HAL_TIMEx_ConfigEncoderIndex(&encoder_handle, &encoder_indexconfig) != HAL_OK)
110+
//{
111+
// SIMPLEFOC_DEBUG("Couldn't configure encoder index pin");
112+
// initialized = false;
113+
// return;
114+
//}
115+
116+
// If index pin provided attach search interrupt
117+
if(hasIndex())
118+
{
119+
attachInterrupt(digitalPinToInterrupt(pinNametoDigitalPin(_pinI)), [this]() {
120+
encoder_handle.Instance->CNT = 0; // reset counter
121+
index_found = true;
122+
// detach interrupt
123+
detachInterrupt(digitalPinToInterrupt(pinNametoDigitalPin(_pinI)));
124+
}, index_polarity);
125+
}
88126

89127
if (HAL_TIM_Encoder_Start(&encoder_handle, TIM_CHANNEL_1) != HAL_OK) {
90128
initialized = false;

src/encoders/stm32hwencoder/STM32HWEncoder.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ class STM32HWEncoder : public Sensor {
2121
void init() override;
2222
int needsSearch() override;
2323
int hasIndex(); // !< function returning 1 if encoder has index pin and 0 if not.
24+
void setCurrentAngle(float set_angle); // !< helper function for setting the angle by using the count register
25+
void setEncoderCount(uint32_t ecount); // !< function for setting the count register
26+
TIM_HandleTypeDef getEncoderTimerHandle(); // !< function for getting the encoder timer handle
2427

2528
bool initialized = false;
2629
uint32_t cpr; //!< encoder cpr number

0 commit comments

Comments
 (0)