Skip to content

Commit ed75944

Browse files
author
Richard Unger
committed
CORDIC trig functions for STM32G4
1 parent 76b356e commit ed75944

File tree

3 files changed

+134
-0
lines changed

3 files changed

+134
-0
lines changed

src/utilities/stm32math/README.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
2+
# SimpleFOC math functions for STM32 CORDIC
3+
4+
Accellerated trigonometry functions are provided for STM32 MCUs having a CORDIC peripheral. The CORDIC hardware can compute sine and cosine values in just a few processor cycles.
5+
6+
## Usage
7+
8+
To use it, set the build-flag `-DHAL_CORDIC_MODULE_ENABLED` for the CORDIC to be enabled in the framework.
9+
10+
Then, include the following in your code:
11+
12+
```c++
13+
#include <Arduino.h>
14+
#include "SimpleFOC.h"
15+
#include "SimpleFOCDrivers.h"
16+
#include "utilities/stm32math/STM32G4CORDICTrigFunctions.h"
17+
18+
void setup() {
19+
...
20+
21+
SimpleFOC_CORDIC_Config(); // initialize the CORDIC
22+
23+
...
24+
}
25+
26+
```
27+
28+
That's it. The faster trig functions will be used automatically by the SimpleFOC code.
29+
30+
You can use them yourself in your own code too:
31+
32+
```c++
33+
34+
float angle = 0.5f; // in radians
35+
float s = _sin(angle);
36+
float c = _cos(angle);
37+
38+
// get both sine and cosine in one operation
39+
_sincos(angle, &s, &c);
40+
41+
```
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
2+
#include "./STM32G4CORDICTrigFunctions.h"
3+
4+
#ifdef HAL_CORDIC_MODULE_ENABLED
5+
6+
#include "Arduino.h"
7+
//#include "stm32g4xx_hal_cordic.h"
8+
#include "stm32g4xx_ll_cordic.h"
9+
#include "stm32g4xx_ll_rcc.h"
10+
#include "stm32g4xx_ll_bus.h"
11+
#include "common/foc_utils.h"
12+
#include "arm_math.h"
13+
14+
CORDIC_HandleTypeDef thisCordic;
15+
16+
bool SimpleFOC_CORDIC_Config(void){
17+
//__HAL_RCC_CORDIC_CLK_ENABLE();
18+
// CORDIC_ConfigTypeDef sConfig;
19+
// thisCordic.Instance = CORDIC;
20+
// if (HAL_CORDIC_Init(&thisCordic) != HAL_OK) {
21+
// Error_Handler();
22+
// return false;
23+
// }
24+
25+
// sConfig.Function = CORDIC_FUNCTION_COSINE;
26+
// sConfig.Precision = CORDIC_PRECISION_6CYCLES;
27+
// sConfig.Scale = CORDIC_SCALE_0;
28+
// sConfig.NbWrite = CORDIC_NBWRITE_1;
29+
// sConfig.NbRead = CORDIC_NBREAD_2;
30+
// sConfig.InSize = CORDIC_INSIZE_32BITS;
31+
// sConfig.OutSize = CORDIC_OUTSIZE_32BITS;
32+
// if (HAL_CORDIC_Configure(&thisCordic, &sConfig) != HAL_OK) {
33+
// /* Channel Configuration Error */
34+
// Error_Handler();
35+
// return false;
36+
// }
37+
38+
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_CORDIC);
39+
LL_CORDIC_Config(CORDIC, LL_CORDIC_FUNCTION_COSINE, /* cosine function */
40+
LL_CORDIC_PRECISION_6CYCLES, /* max precision for q1.31 cosine */
41+
LL_CORDIC_SCALE_0, /* no scale */
42+
LL_CORDIC_NBWRITE_1, /* One input data: angle. Second input data (modulus) is 1 after cordic reset */
43+
LL_CORDIC_NBREAD_2, /* Two output data: cosine, then sine */
44+
LL_CORDIC_INSIZE_32BITS, /* q1.31 format for input data */
45+
LL_CORDIC_OUTSIZE_32BITS); /* q1.31 format for output data */
46+
return true;
47+
};
48+
49+
50+
51+
float _sin(float a) {
52+
a = fmod(a, _2PI);
53+
if (a>_PI) a -= _2PI;
54+
if (a<-_PI) a += _2PI;
55+
CORDIC->WDATA = (q31_t)((a / _PI) * 0x80000000);
56+
q31_t out_cos = (int32_t)CORDIC->RDATA; // read cosine result
57+
q31_t out_sin = (int32_t)CORDIC->RDATA; // read sine result
58+
return (float)out_sin / (float)0x80000000;
59+
}
60+
61+
float _cos(float a) {
62+
a = fmod(a, _2PI);
63+
if (a>_PI) a -= _2PI;
64+
if (a<-_PI) a += _2PI;
65+
CORDIC->WDATA = (q31_t)((a / _PI) * 0x80000000);
66+
q31_t out_cos = (int32_t)CORDIC->RDATA; // read cosine result
67+
q31_t out_sin = (int32_t)CORDIC->RDATA; // read sine result
68+
return (float)out_cos / (float)0x80000000;
69+
}
70+
71+
void _sincos(float a, float* s, float* c) {
72+
a = fmod(a, _2PI);
73+
if (a>_PI) a -= _2PI;
74+
if (a<-_PI) a += _2PI;
75+
CORDIC->WDATA = (q31_t)((a / _PI) * 0x80000000);
76+
q31_t out_cos = (int32_t)CORDIC->RDATA; // read cosine result
77+
q31_t out_sin = (int32_t)CORDIC->RDATA; // read sine result
78+
*c = (float)out_cos / (float)0x80000000;
79+
*s = (float)out_sin / (float)0x80000000;
80+
}
81+
82+
83+
#endif
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
#pragma once
3+
4+
#ifdef HAL_CORDIC_MODULE_ENABLED
5+
6+
7+
bool SimpleFOC_CORDIC_Config(void);
8+
9+
10+
#endif

0 commit comments

Comments
 (0)