Skip to content

Commit ba3dabd

Browse files
committed
Add atan2 support using stm cordic
1 parent ae40a7a commit ba3dabd

File tree

1 file changed

+43
-15
lines changed

1 file changed

+43
-15
lines changed

src/utilities/stm32math/STM32G4CORDICTrigFunctions.cpp

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -46,38 +46,66 @@ bool SimpleFOC_CORDIC_Config(void){
4646
return true;
4747
};
4848

49+
static bool arg2_modified = false;
4950

5051

5152
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;
53+
float s, c;
54+
_sincos(a, &s, &c);
55+
return s;
5956
}
6057

6158
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;
59+
float s, c;
60+
_sincos(a, &s, &c);
61+
return c;
6962
}
7063

7164
void _sincos(float a, float* s, float* c) {
7265
a = fmod(a, _2PI);
7366
if (a>_PI) a -= _2PI;
74-
if (a<-_PI) a += _2PI;
67+
if (a<-_PI) a += _2PI;
68+
LL_CORDIC_SetFunction(CORDIC, LL_CORDIC_FUNCTION_COSINE);
7569
CORDIC->WDATA = (q31_t)((a / _PI) * 0x80000000);
70+
if (arg2_modified)
71+
{
72+
CORDIC->WDATA = (q31_t)((1.f) * 0x80000000);
73+
}
7674
q31_t out_cos = (int32_t)CORDIC->RDATA; // read cosine result
7775
q31_t out_sin = (int32_t)CORDIC->RDATA; // read sine result
7876
*c = (float)out_cos / (float)0x80000000;
7977
*s = (float)out_sin / (float)0x80000000;
78+
if (arg2_modified)
79+
{
80+
LL_CORDIC_SetNbWrite(CORDIC, LL_CORDIC_NBWRITE_1);
81+
arg2_modified = false;
82+
}
8083
}
8184

85+
void _atan2mod(float y, float x, float* phase, float* modulus)
86+
{
87+
float absx = abs(x), absy = abs(y);
88+
float xbigger = abs(x) >= abs(y);
89+
float scaler = (xbigger ? absx : absy) * 1.5f; //multiply scaler by 1.5 to avoid saturating modulus
90+
LL_CORDIC_SetFunction(CORDIC, LL_CORDIC_FUNCTION_PHASE);
91+
if (!arg2_modified)
92+
{
93+
arg2_modified = true;
94+
LL_CORDIC_SetNbWrite(CORDIC, LL_CORDIC_NBWRITE_2);
95+
}
96+
CORDIC->WDATA = (q31_t)((x / scaler) * 0x80000000);
97+
CORDIC->WDATA = (q31_t)((y / scaler) * 0x80000000);
98+
q31_t out_phase = (int32_t)CORDIC->RDATA; // read phase result
99+
q31_t out_modulus = (int32_t)CORDIC->RDATA; // read modulus result
100+
*phase = (float)out_phase * _PI / (float)0x80000000;
101+
*modulus = (float)out_modulus / (float)0x80000000 * scaler;
102+
}
103+
104+
float _atan2(float y, float x)
105+
{
106+
float phase, modulus;
107+
_atan2mod(y, x, &phase, &modulus);
108+
return phase;
109+
}
82110

83111
#endif

0 commit comments

Comments
 (0)