mc_math.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. /**
  2. ******************************************************************************
  3. * @file mc_math.c
  4. * @author Motor Control SDK Team, ST Microelectronics
  5. * @brief This file provides mathematics functions useful for and specific to
  6. * Motor Control.
  7. *
  8. ******************************************************************************
  9. * @attention
  10. *
  11. * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
  12. * All rights reserved.</center></h2>
  13. *
  14. * This software component is licensed by ST under Ultimate Liberty license
  15. * SLA0044, the "License"; You may not use this file except in compliance with
  16. * the License. You may obtain a copy of the License at:
  17. * www.st.com/SLA0044
  18. *
  19. ******************************************************************************
  20. */
  21. /* Includes ------------------------------------------------------------------*/
  22. #include "mc_math.h"
  23. #include "mc_type.h"
  24. /** @addtogroup MCSDK
  25. * @{
  26. */
  27. /** @defgroup MC_Math Motor Control Math functions
  28. * @brief Motor Control Mathematic functions of the Motor Control SDK
  29. *
  30. * @todo Document the Motor Control Math "module".
  31. *
  32. * @{
  33. */
  34. /* Private macro -------------------------------------------------------------*/
  35. #define SIN_COS_TABLE {\
  36. 0x0000,0x00C9,0x0192,0x025B,0x0324,0x03ED,0x04B6,0x057F,\
  37. 0x0648,0x0711,0x07D9,0x08A2,0x096A,0x0A33,0x0AFB,0x0BC4,\
  38. 0x0C8C,0x0D54,0x0E1C,0x0EE3,0x0FAB,0x1072,0x113A,0x1201,\
  39. 0x12C8,0x138F,0x1455,0x151C,0x15E2,0x16A8,0x176E,0x1833,\
  40. 0x18F9,0x19BE,0x1A82,0x1B47,0x1C0B,0x1CCF,0x1D93,0x1E57,\
  41. 0x1F1A,0x1FDD,0x209F,0x2161,0x2223,0x22E5,0x23A6,0x2467,\
  42. 0x2528,0x25E8,0x26A8,0x2767,0x2826,0x28E5,0x29A3,0x2A61,\
  43. 0x2B1F,0x2BDC,0x2C99,0x2D55,0x2E11,0x2ECC,0x2F87,0x3041,\
  44. 0x30FB,0x31B5,0x326E,0x3326,0x33DF,0x3496,0x354D,0x3604,\
  45. 0x36BA,0x376F,0x3824,0x38D9,0x398C,0x3A40,0x3AF2,0x3BA5,\
  46. 0x3C56,0x3D07,0x3DB8,0x3E68,0x3F17,0x3FC5,0x4073,0x4121,\
  47. 0x41CE,0x427A,0x4325,0x43D0,0x447A,0x4524,0x45CD,0x4675,\
  48. 0x471C,0x47C3,0x4869,0x490F,0x49B4,0x4A58,0x4AFB,0x4B9D,\
  49. 0x4C3F,0x4CE0,0x4D81,0x4E20,0x4EBF,0x4F5D,0x4FFB,0x5097,\
  50. 0x5133,0x51CE,0x5268,0x5302,0x539B,0x5432,0x54C9,0x5560,\
  51. 0x55F5,0x568A,0x571D,0x57B0,0x5842,0x58D3,0x5964,0x59F3,\
  52. 0x5A82,0x5B0F,0x5B9C,0x5C28,0x5CB3,0x5D3E,0x5DC7,0x5E4F,\
  53. 0x5ED7,0x5F5D,0x5FE3,0x6068,0x60EB,0x616E,0x61F0,0x6271,\
  54. 0x62F1,0x6370,0x63EE,0x646C,0x64E8,0x6563,0x65DD,0x6656,\
  55. 0x66CF,0x6746,0x67BC,0x6832,0x68A6,0x6919,0x698B,0x69FD,\
  56. 0x6A6D,0x6ADC,0x6B4A,0x6BB7,0x6C23,0x6C8E,0x6CF8,0x6D61,\
  57. 0x6DC9,0x6E30,0x6E96,0x6EFB,0x6F5E,0x6FC1,0x7022,0x7083,\
  58. 0x70E2,0x7140,0x719D,0x71F9,0x7254,0x72AE,0x7307,0x735E,\
  59. 0x73B5,0x740A,0x745F,0x74B2,0x7504,0x7555,0x75A5,0x75F3,\
  60. 0x7641,0x768D,0x76D8,0x7722,0x776B,0x77B3,0x77FA,0x783F,\
  61. 0x7884,0x78C7,0x7909,0x794A,0x7989,0x79C8,0x7A05,0x7A41,\
  62. 0x7A7C,0x7AB6,0x7AEE,0x7B26,0x7B5C,0x7B91,0x7BC5,0x7BF8,\
  63. 0x7C29,0x7C59,0x7C88,0x7CB6,0x7CE3,0x7D0E,0x7D39,0x7D62,\
  64. 0x7D89,0x7DB0,0x7DD5,0x7DFA,0x7E1D,0x7E3E,0x7E5F,0x7E7E,\
  65. 0x7E9C,0x7EB9,0x7ED5,0x7EEF,0x7F09,0x7F21,0x7F37,0x7F4D,\
  66. 0x7F61,0x7F74,0x7F86,0x7F97,0x7FA6,0x7FB4,0x7FC1,0x7FCD,\
  67. 0x7FD8,0x7FE1,0x7FE9,0x7FF0,0x7FF5,0x7FF9,0x7FFD,0x7FFE}
  68. #define ATAN1DIV1 (int16_t)8192
  69. #define ATAN1DIV2 (int16_t)4836
  70. #define ATAN1DIV4 (int16_t)2555
  71. #define ATAN1DIV8 (int16_t)1297
  72. #define ATAN1DIV16 (int16_t)651
  73. #define ATAN1DIV32 (int16_t)326
  74. #define ATAN1DIV64 (int16_t)163
  75. #define ATAN1DIV128 (int16_t)81
  76. #define ATAN1DIV256 (int16_t)41
  77. #define ATAN1DIV512 (int16_t)20
  78. #define ATAN1DIV1024 (int16_t)10
  79. #define ATAN1DIV2048 (int16_t)5
  80. #define ATAN1DIV4096 (int16_t)3
  81. #define ATAN1DIV8192 (int16_t)1
  82. #define SIN_MASK 0x0300u
  83. #define U0_90 0x0200u
  84. #define U90_180 0x0300u
  85. #define U180_270 0x0000u
  86. #define U270_360 0x0100u
  87. /* Private variables ---------------------------------------------------------*/
  88. const int16_t hSin_Cos_Table[256] = SIN_COS_TABLE;
  89. #define divSQRT_3 (int32_t)0x49E6 /* 1/sqrt(3) in q1.15 format=0.5773315*/
  90. #if defined (CCMRAM)
  91. #if defined (__ICCARM__)
  92. #pragma location = ".ccmram"
  93. #elif defined (__CC_ARM) || defined(__GNUC__)
  94. __attribute__( ( section ( ".ccmram" ) ) )
  95. #endif
  96. #endif
  97. /**
  98. * @brief This function transforms stator values a and b (which are
  99. * directed along axes each displaced by 120 degrees) into values
  100. * alpha and beta in a stationary qd reference frame.
  101. * alpha = a
  102. * beta = -(2*b+a)/sqrt(3)
  103. * @param Input: stator values a and b in ab_t format
  104. * @retval Stator values alpha and beta in alphabeta_t format
  105. */
  106. __weak alphabeta_t MCM_Clarke( ab_t Input )
  107. {
  108. alphabeta_t Output;
  109. int32_t a_divSQRT3_tmp, b_divSQRT3_tmp ;
  110. int32_t wbeta_tmp;
  111. int16_t hbeta_tmp;
  112. /* qIalpha = qIas*/
  113. Output.alpha = Input.a;
  114. a_divSQRT3_tmp = divSQRT_3 * ( int32_t )Input.a;
  115. b_divSQRT3_tmp = divSQRT_3 * ( int32_t )Input.b;
  116. /*qIbeta = -(2*qIbs+qIas)/sqrt(3)*/
  117. #ifdef FULL_MISRA_C_COMPLIANCY
  118. wbeta_tmp = ( -( a_divSQRT3_tmp ) - ( b_divSQRT3_tmp ) -
  119. ( b_divSQRT3_tmp ) ) / 32768;
  120. #else
  121. /* WARNING: the below instruction is not MISRA compliant, user should verify
  122. that Cortex-M3 assembly instruction ASR (arithmetic shift right) is used by
  123. the compiler to perform the shift (instead of LSR logical shift right) */
  124. wbeta_tmp = ( -( a_divSQRT3_tmp ) - ( b_divSQRT3_tmp ) -
  125. ( b_divSQRT3_tmp ) ) >> 15;
  126. #endif
  127. /* Check saturation of Ibeta */
  128. if ( wbeta_tmp > INT16_MAX )
  129. {
  130. hbeta_tmp = INT16_MAX;
  131. }
  132. else if ( wbeta_tmp < ( -32768 ) )
  133. {
  134. hbeta_tmp = ( -32768 );
  135. }
  136. else
  137. {
  138. hbeta_tmp = ( int16_t )( wbeta_tmp );
  139. }
  140. Output.beta = hbeta_tmp;
  141. if ( Output.beta == ( int16_t )( -32768 ) )
  142. {
  143. Output.beta = -32767;
  144. }
  145. return ( Output );
  146. }
  147. #if defined (CCMRAM)
  148. #if defined (__ICCARM__)
  149. #pragma location = ".ccmram"
  150. #elif defined (__CC_ARM) || defined(__GNUC__)
  151. __attribute__( ( section ( ".ccmram" ) ) )
  152. #endif
  153. #endif
  154. /**
  155. * @brief This function transforms stator values alpha and beta, which
  156. * belong to a stationary qd reference frame, to a rotor flux
  157. * synchronous reference frame (properly oriented), so as q and d.
  158. * d= alpha *sin(theta)+ beta *cos(Theta)
  159. * q= alpha *cos(Theta)- beta *sin(Theta)
  160. * @param Input: stator values alpha and beta in alphabeta_t format
  161. * @param Theta: rotating frame angular position in q1.15 format
  162. * @retval Stator values q and d in qd_t format
  163. */
  164. __weak qd_t MCM_Park( alphabeta_t Input, int16_t Theta )
  165. {
  166. qd_t Output;
  167. int32_t d_tmp_1, d_tmp_2, q_tmp_1, q_tmp_2;
  168. Trig_Components Local_Vector_Components;
  169. int32_t wqd_tmp;
  170. int16_t hqd_tmp;
  171. Local_Vector_Components = MCM_Trig_Functions( Theta );
  172. /*No overflow guaranteed*/
  173. q_tmp_1 = Input.alpha * ( int32_t )Local_Vector_Components.hCos;
  174. /*No overflow guaranteed*/
  175. q_tmp_2 = Input.beta * ( int32_t )Local_Vector_Components.hSin;
  176. /*Iq component in Q1.15 Format */
  177. #ifdef FULL_MISRA_C_COMPLIANCY
  178. wqd_tmp = ( q_tmp_1 - q_tmp_2 ) / 32768;
  179. #else
  180. /* WARNING: the below instruction is not MISRA compliant, user should verify
  181. that Cortex-M3 assembly instruction ASR (arithmetic shift right) is used by
  182. the compiler to perform the shift (instead of LSR logical shift right) */
  183. wqd_tmp = ( q_tmp_1 - q_tmp_2 ) >> 15;
  184. #endif
  185. /* Check saturation of Iq */
  186. if ( wqd_tmp > INT16_MAX )
  187. {
  188. hqd_tmp = INT16_MAX;
  189. }
  190. else if ( wqd_tmp < ( -32768 ) )
  191. {
  192. hqd_tmp = ( -32768 );
  193. }
  194. else
  195. {
  196. hqd_tmp = ( int16_t )( wqd_tmp );
  197. }
  198. Output.q = hqd_tmp;
  199. if ( Output.q == ( int16_t )( -32768 ) )
  200. {
  201. Output.q = -32767;
  202. }
  203. /*No overflow guaranteed*/
  204. d_tmp_1 = Input.alpha * ( int32_t )Local_Vector_Components.hSin;
  205. /*No overflow guaranteed*/
  206. d_tmp_2 = Input.beta * ( int32_t )Local_Vector_Components.hCos;
  207. /*Id component in Q1.15 Format */
  208. #ifdef FULL_MISRA_C_COMPLIANCY
  209. wqd_tmp = ( d_tmp_1 + d_tmp_2 ) / 32768;
  210. #else
  211. /* WARNING: the below instruction is not MISRA compliant, user should verify
  212. that Cortex-M3 assembly instruction ASR (arithmetic shift right) is used by
  213. the compiler to perform the shift (instead of LSR logical shift right) */
  214. wqd_tmp = ( d_tmp_1 + d_tmp_2 ) >> 15;
  215. #endif
  216. /* Check saturation of Id */
  217. if ( wqd_tmp > INT16_MAX )
  218. {
  219. hqd_tmp = INT16_MAX;
  220. }
  221. else if ( wqd_tmp < ( -32768 ) )
  222. {
  223. hqd_tmp = ( -32768 );
  224. }
  225. else
  226. {
  227. hqd_tmp = ( int16_t )( wqd_tmp );
  228. }
  229. Output.d = hqd_tmp;
  230. if ( Output.d == ( int16_t )( -32768 ) )
  231. {
  232. Output.d = -32767;
  233. }
  234. return ( Output );
  235. }
  236. #if defined (CCMRAM)
  237. #if defined (__ICCARM__)
  238. #pragma location = ".ccmram"
  239. #elif defined (__CC_ARM) || defined(__GNUC__)
  240. __attribute__( ( section ( ".ccmram" ) ) )
  241. #endif
  242. #endif
  243. /**
  244. * @brief This function transforms stator voltage qVq and qVd, that belong to
  245. * a rotor flux synchronous rotating frame, to a stationary reference
  246. * frame, so as to obtain qValpha and qVbeta:
  247. * Valfa= Vq*Cos(theta)+ Vd*Sin(theta)
  248. * Vbeta=-Vq*Sin(theta)+ Vd*Cos(theta)
  249. * @param Input: stator voltage Vq and Vd in qd_t format
  250. * @param Theta: rotating frame angular position in q1.15 format
  251. * @retval Stator voltage Valpha and Vbeta in qd_t format
  252. */
  253. __weak alphabeta_t MCM_Rev_Park( qd_t Input, int16_t Theta )
  254. {
  255. int32_t alpha_tmp1, alpha_tmp2, beta_tmp1, beta_tmp2;
  256. Trig_Components Local_Vector_Components;
  257. alphabeta_t Output;
  258. Local_Vector_Components = MCM_Trig_Functions( Theta );
  259. /*No overflow guaranteed*/
  260. alpha_tmp1 = Input.q * ( int32_t )Local_Vector_Components.hCos;
  261. alpha_tmp2 = Input.d * ( int32_t )Local_Vector_Components.hSin;
  262. #ifdef FULL_MISRA_C_COMPLIANCY
  263. Output.alpha = ( int16_t )( ( ( alpha_tmp1 ) + ( alpha_tmp2 ) ) / 32768 );
  264. #else
  265. /* WARNING: the below instruction is not MISRA compliant, user should verify
  266. that Cortex-M3 assembly instruction ASR (arithmetic shift right) is used by
  267. the compiler to perform the shift (instead of LSR logical shift right) */
  268. Output.alpha = ( int16_t )( ( ( alpha_tmp1 ) + ( alpha_tmp2 ) ) >> 15 );
  269. #endif
  270. beta_tmp1 = Input.q * ( int32_t )Local_Vector_Components.hSin;
  271. beta_tmp2 = Input.d * ( int32_t )Local_Vector_Components.hCos;
  272. #ifdef FULL_MISRA_C_COMPLIANCY
  273. Output.beta = ( int16_t )( ( beta_tmp2 - beta_tmp1 ) / 32768 );
  274. #else
  275. /* WARNING: the below instruction is not MISRA compliant, user should verify
  276. that Cortex-M3 assembly instruction ASR (arithmetic shift right) is used by
  277. the compiler to perform the shift (instead of LSR logical shift right) */
  278. Output.beta = ( int16_t )( ( beta_tmp2 - beta_tmp1 ) >> 15 );
  279. #endif
  280. return ( Output );
  281. }
  282. #if defined (CCMRAM)
  283. #if defined (__ICCARM__)
  284. #pragma location = ".ccmram"
  285. #elif defined (__CC_ARM) || defined(__GNUC__)
  286. __attribute__( ( section ( ".ccmram" ) ) )
  287. #endif
  288. #endif
  289. /**
  290. * @brief This function returns cosine and sine functions of the angle fed in
  291. * input
  292. * @param hAngle: angle in q1.15 format
  293. * @retval Sin(angle) and Cos(angle) in Trig_Components format
  294. */
  295. __weak Trig_Components MCM_Trig_Functions( int16_t hAngle )
  296. {
  297. int32_t shindex;
  298. uint16_t uhindex;
  299. Trig_Components Local_Components;
  300. /* 10 bit index computation */
  301. shindex = ( ( int32_t )32768 + ( int32_t )hAngle );
  302. uhindex = ( uint16_t )shindex;
  303. uhindex /= ( uint16_t )64;
  304. switch ( ( uint16_t )( uhindex ) & SIN_MASK )
  305. {
  306. case U0_90:
  307. Local_Components.hSin = hSin_Cos_Table[( uint8_t )( uhindex )];
  308. Local_Components.hCos = hSin_Cos_Table[( uint8_t )( 0xFFu - ( uint8_t )( uhindex ) )];
  309. break;
  310. case U90_180:
  311. Local_Components.hSin = hSin_Cos_Table[( uint8_t )( 0xFFu - ( uint8_t )( uhindex ) )];
  312. Local_Components.hCos = -hSin_Cos_Table[( uint8_t )( uhindex )];
  313. break;
  314. case U180_270:
  315. Local_Components.hSin = -hSin_Cos_Table[( uint8_t )( uhindex )];
  316. Local_Components.hCos = -hSin_Cos_Table[( uint8_t )( 0xFFu - ( uint8_t )( uhindex ) )];
  317. break;
  318. case U270_360:
  319. Local_Components.hSin = -hSin_Cos_Table[( uint8_t )( 0xFFu - ( uint8_t )( uhindex ) )];
  320. Local_Components.hCos = hSin_Cos_Table[( uint8_t )( uhindex )];
  321. break;
  322. default:
  323. break;
  324. }
  325. return ( Local_Components );
  326. }
  327. #if defined (CCMRAM)
  328. #if defined (__ICCARM__)
  329. #pragma location = ".ccmram"
  330. #elif defined (__CC_ARM) || defined(__GNUC__)
  331. __attribute__( ( section ( ".ccmram" ) ) )
  332. #endif
  333. #endif
  334. /**
  335. * @brief It calculates the square root of a non-negative int32_t. It returns 0
  336. * for negative int32_t.
  337. * @param Input int32_t number
  338. * @retval int32_t Square root of Input (0 if Input<0)
  339. */
  340. __weak int32_t MCM_Sqrt( int32_t wInput )
  341. {
  342. int32_t wtemprootnew;
  343. if ( wInput > 0 )
  344. {
  345. uint8_t biter = 0u;
  346. int32_t wtemproot;
  347. if ( wInput <= ( int32_t )2097152 )
  348. {
  349. wtemproot = ( int32_t )128;
  350. }
  351. else
  352. {
  353. wtemproot = ( int32_t )8192;
  354. }
  355. do
  356. {
  357. wtemprootnew = ( wtemproot + wInput / wtemproot ) / ( int32_t )2;
  358. if ( wtemprootnew == wtemproot )
  359. {
  360. biter = 6u;
  361. }
  362. else
  363. {
  364. biter ++;
  365. wtemproot = wtemprootnew;
  366. }
  367. }
  368. while ( biter < 6u );
  369. }
  370. else
  371. {
  372. wtemprootnew = ( int32_t )0;
  373. }
  374. return ( wtemprootnew );
  375. }
  376. /**
  377. * @brief It executes CORDIC algorithm for rotor position extraction from B-emf
  378. * alpha and beta
  379. * @param wBemf_alfa_est estimated Bemf alpha on the stator reference frame
  380. * wBemf_beta_est estimated Bemf beta on the stator reference frame
  381. * @retval int16_t rotor electrical angle (s16degrees)
  382. */
  383. inline int16_t MCM_PhaseComputation( int32_t wBemf_alfa_est, int32_t wBemf_beta_est )
  384. {
  385. int16_t hAngle;
  386. int32_t wXi, wYi, wXold;
  387. /*Determining quadrant*/
  388. if ( wBemf_alfa_est < 0 )
  389. {
  390. if ( wBemf_beta_est < 0 )
  391. {
  392. /*Quadrant III, add 90 degrees so as to move to quadrant IV*/
  393. hAngle = 16384;
  394. wXi = - ( wBemf_beta_est / 2 );
  395. wYi = wBemf_alfa_est / 2;
  396. }
  397. else
  398. {
  399. /*Quadrant II, subtract 90 degrees so as to move to quadrant I*/
  400. hAngle = -16384;
  401. wXi = wBemf_beta_est / 2;
  402. wYi = - ( wBemf_alfa_est / 2 );
  403. }
  404. }
  405. else
  406. {
  407. /* Quadrant I or IV*/
  408. hAngle = 0;
  409. wXi = wBemf_alfa_est / 2;
  410. wYi = wBemf_beta_est / 2;
  411. }
  412. wXold = wXi;
  413. /*begin the successive approximation process*/
  414. /*iteration0*/
  415. if ( wYi < 0 )
  416. {
  417. /*vector is in Quadrant IV*/
  418. hAngle += ATAN1DIV1;
  419. wXi = wXi - wYi;
  420. wYi = wXold + wYi;
  421. }
  422. else
  423. {
  424. /*vector is in Quadrant I*/
  425. hAngle -= ATAN1DIV1;
  426. wXi = wXi + wYi;
  427. wYi = -wXold + wYi;
  428. }
  429. wXold = wXi;
  430. /*iteration1*/
  431. if ( wYi < 0 )
  432. {
  433. /*vector is in Quadrant IV*/
  434. hAngle += ATAN1DIV2;
  435. wXi = wXi - wYi / 2;
  436. wYi = wXold / 2 + wYi;
  437. }
  438. else
  439. {
  440. /*vector is in Quadrant I*/
  441. hAngle -= ATAN1DIV2;
  442. wXi = wXi + wYi / 2;
  443. wYi = -wXold / 2 + wYi;
  444. }
  445. wXold = wXi;
  446. /*iteration2*/
  447. if ( wYi < 0 )
  448. {
  449. /*vector is in Quadrant IV*/
  450. hAngle += ATAN1DIV4;
  451. wXi = wXi - wYi / 4;
  452. wYi = wXold / 4 + wYi;
  453. }
  454. else
  455. {
  456. /*vector is in Quadrant I*/
  457. hAngle -= ATAN1DIV4;
  458. wXi = wXi + wYi / 4;
  459. wYi = -wXold / 4 + wYi;
  460. }
  461. wXold = wXi;
  462. /*iteration3*/
  463. if ( wYi < 0 )
  464. {
  465. /*vector is in Quadrant IV*/
  466. hAngle += ATAN1DIV8;
  467. wXi = wXi - wYi / 8;
  468. wYi = wXold / 8 + wYi;
  469. }
  470. else
  471. {
  472. /*vector is in Quadrant I*/
  473. hAngle -= ATAN1DIV8;
  474. wXi = wXi + wYi / 8;
  475. wYi = -wXold / 8 + wYi;
  476. }
  477. wXold = wXi;
  478. /*iteration4*/
  479. if ( wYi < 0 )
  480. {
  481. /*vector is in Quadrant IV*/
  482. hAngle += ATAN1DIV16;
  483. wXi = wXi - wYi / 16;
  484. wYi = wXold / 16 + wYi;
  485. }
  486. else
  487. {
  488. /*vector is in Quadrant I*/
  489. hAngle -= ATAN1DIV16;
  490. wXi = wXi + wYi / 16;
  491. wYi = -wXold / 16 + wYi;
  492. }
  493. wXold = wXi;
  494. /*iteration5*/
  495. if ( wYi < 0 )
  496. {
  497. /*vector is in Quadrant IV*/
  498. hAngle += ATAN1DIV32;
  499. wXi = wXi - wYi / 32;
  500. wYi = wXold / 32 + wYi;
  501. }
  502. else
  503. {
  504. /*vector is in Quadrant I*/
  505. hAngle -= ATAN1DIV32;
  506. wXi = wXi + wYi / 32;
  507. wYi = -wXold / 32 + wYi;
  508. }
  509. wXold = wXi;
  510. /*iteration6*/
  511. if ( wYi < 0 )
  512. {
  513. /*vector is in Quadrant IV*/
  514. hAngle += ATAN1DIV64;
  515. wXi = wXi - wYi / 64;
  516. wYi = wXold / 64 + wYi;
  517. }
  518. else
  519. {
  520. /*vector is in Quadrant I*/
  521. hAngle -= ATAN1DIV64;
  522. wXi = wXi + wYi / 64;
  523. wYi = -wXold / 64 + wYi;
  524. }
  525. wXold = wXi;
  526. /*iteration7*/
  527. if ( wYi < 0 )
  528. {
  529. /*vector is in Quadrant IV*/
  530. hAngle += ATAN1DIV128;
  531. wXi = wXi - wYi / 128;
  532. wYi = wXold / 128 + wYi;
  533. }
  534. else
  535. {
  536. /*vector is in Quadrant I*/
  537. hAngle -= ATAN1DIV128;
  538. wXi = wXi + wYi / 128;
  539. wYi = -wXold / 128 + wYi;
  540. }
  541. return ( -hAngle );
  542. }
  543. /**
  544. * @brief This function codify a floating point number into the relative
  545. * 32bit integer.
  546. * @param float Floating point number to be coded.
  547. * @retval uint32_t Coded 32bit integer.
  548. */
  549. __weak uint32_t MCM_floatToIntBit( float x )
  550. {
  551. uint32_t * pInt;
  552. pInt = ( uint32_t * )( &x );
  553. return *pInt;
  554. }
  555. /**
  556. * @}
  557. */
  558. /**
  559. * @}
  560. */
  561. /******************* (C) COPYRIGHT 2019 STMicroelectronics *****END OF FILE****/