controller_functions.h 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788
  1. /******************************************************************************
  2. * @file controller_functions.h
  3. * @brief Public header file for NMSIS DSP Library
  4. * @version V1.10.0
  5. * @date 08 July 2021
  6. * Target Processor: RISC-V Cores
  7. ******************************************************************************/
  8. /*
  9. * Copyright (c) 2010-2020 Arm Limited or its affiliates. All rights reserved.
  10. * Copyright (c) 2019 Nuclei Limited. All rights reserved.
  11. *
  12. * SPDX-License-Identifier: Apache-2.0
  13. *
  14. * Licensed under the Apache License, Version 2.0 (the License); you may
  15. * not use this file except in compliance with the License.
  16. * You may obtain a copy of the License at
  17. *
  18. * www.apache.org/licenses/LICENSE-2.0
  19. *
  20. * Unless required by applicable law or agreed to in writing, software
  21. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  22. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  23. * See the License for the specific language governing permissions and
  24. * limitations under the License.
  25. */
  26. #ifndef CONTROLLER_FUNCTIONS_H_
  27. #define CONTROLLER_FUNCTIONS_H_
  28. #include "riscv_math_types.h"
  29. #include "riscv_math_memory.h"
  30. #include "dsp/none.h"
  31. #include "dsp/utils.h"
  32. #ifdef __cplusplus
  33. extern "C"
  34. {
  35. #endif
  36. /**
  37. * @brief Macros required for SINE and COSINE Controller functions
  38. */
  39. #define CONTROLLER_Q31_SHIFT (32 - 9)
  40. /* 1.31(q31) Fixed value of 2/360 */
  41. /* -1 to +1 is divided into 360 values so total spacing is (2/360) */
  42. #define INPUT_SPACING 0xB60B61
  43. /**
  44. * @defgroup groupController Controller Functions
  45. */
  46. /**
  47. @ingroup groupController
  48. */
  49. /**
  50. @defgroup SinCos Sine Cosine
  51. Computes the trigonometric sine and cosine values using a combination of table lookup
  52. and linear interpolation.
  53. There are separate functions for Q31 and floating-point data types.
  54. The input to the floating-point version is in degrees while the
  55. fixed-point Q31 have a scaled input with the range
  56. [-1 0.9999] mapping to [-180 +180] degrees.
  57. The floating point function also allows values that are out of the usual range. When this happens, the function will
  58. take extra time to adjust the input value to the range of [-180 180].
  59. The result is accurate to 5 digits after the decimal point.
  60. The implementation is based on table lookup using 360 values together with linear interpolation.
  61. The steps used are:
  62. -# Calculation of the nearest integer table index.
  63. -# Compute the fractional portion (fract) of the input.
  64. -# Fetch the value corresponding to \c index from sine table to \c y0 and also value from \c index+1 to \c y1.
  65. -# Sine value is computed as <code> *psinVal = y0 + (fract * (y1 - y0))</code>.
  66. -# Fetch the value corresponding to \c index from cosine table to \c y0 and also value from \c index+1 to \c y1.
  67. -# Cosine value is computed as <code> *pcosVal = y0 + (fract * (y1 - y0))</code>.
  68. */
  69. /**
  70. * @brief Floating-point sin_cos function.
  71. * @param[in] theta input value in degrees
  72. * @param[out] pSinVal points to the processed sine output.
  73. * @param[out] pCosVal points to the processed cos output.
  74. */
  75. void riscv_sin_cos_f32(
  76. float32_t theta,
  77. float32_t * pSinVal,
  78. float32_t * pCosVal);
  79. /**
  80. * @brief Q31 sin_cos function.
  81. * @param[in] theta scaled input value in degrees
  82. * @param[out] pSinVal points to the processed sine output.
  83. * @param[out] pCosVal points to the processed cosine output.
  84. */
  85. void riscv_sin_cos_q31(
  86. q31_t theta,
  87. q31_t * pSinVal,
  88. q31_t * pCosVal);
  89. /**
  90. @ingroup groupController
  91. */
  92. /**
  93. * @defgroup PID PID Motor Control
  94. *
  95. * A Proportional Integral Derivative (PID) controller is a generic feedback control
  96. * loop mechanism widely used in industrial control systems.
  97. * A PID controller is the most commonly used type of feedback controller.
  98. *
  99. * This set of functions implements (PID) controllers
  100. * for Q15, Q31, and floating-point data types. The functions operate on a single sample
  101. * of data and each call to the function returns a single processed value.
  102. * <code>S</code> points to an instance of the PID control data structure. <code>in</code>
  103. * is the input sample value. The functions return the output value.
  104. *
  105. * \par Algorithm:
  106. * <pre>
  107. * y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
  108. * A0 = Kp + Ki + Kd
  109. * A1 = (-Kp ) - (2 * Kd )
  110. * A2 = Kd
  111. * </pre>
  112. *
  113. * \par
  114. * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant
  115. *
  116. * \par
  117. * \image html PID.png "Proportional Integral Derivative Controller"
  118. *
  119. * \par
  120. * The PID controller calculates an "error" value as the difference between
  121. * the measured output and the reference input.
  122. * The controller attempts to minimize the error by adjusting the process control inputs.
  123. * The proportional value determines the reaction to the current error,
  124. * the integral value determines the reaction based on the sum of recent errors,
  125. * and the derivative value determines the reaction based on the rate at which the error has been changing.
  126. *
  127. * \par Instance Structure
  128. * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure.
  129. * A separate instance structure must be defined for each PID Controller.
  130. * There are separate instance structure declarations for each of the 3 supported data types.
  131. *
  132. * \par Reset Functions
  133. * There is also an associated reset function for each data type which clears the state array.
  134. *
  135. * \par Initialization Functions
  136. * There is also an associated initialization function for each data type.
  137. * The initialization function performs the following operations:
  138. * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains.
  139. * - Zeros out the values in the state buffer.
  140. *
  141. * \par
  142. * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function.
  143. *
  144. * \par Fixed-Point Behavior
  145. * Care must be taken when using the fixed-point versions of the PID Controller functions.
  146. * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered.
  147. * Refer to the function specific documentation below for usage guidelines.
  148. */
  149. /**
  150. * @ingroup PID
  151. * @brief Instance structure for the Q15 PID Control.
  152. */
  153. typedef struct
  154. {
  155. q15_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */
  156. #if !defined (RISCV_MATH_DSP)
  157. q15_t A1; /**< The derived gain A1 = -Kp - 2Kd */
  158. q15_t A2; /**< The derived gain A1 = Kd. */
  159. #else
  160. q31_t A1; /**< The derived gain A1 = -Kp - 2Kd | Kd.*/
  161. #endif
  162. q15_t state[3]; /**< The state array of length 3. */
  163. q15_t Kp; /**< The proportional gain. */
  164. q15_t Ki; /**< The integral gain. */
  165. q15_t Kd; /**< The derivative gain. */
  166. } riscv_pid_instance_q15;
  167. /**
  168. * @ingroup PID
  169. * @brief Instance structure for the Q31 PID Control.
  170. */
  171. typedef struct
  172. {
  173. q31_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */
  174. q31_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */
  175. q31_t A2; /**< The derived gain, A2 = Kd . */
  176. q31_t state[3]; /**< The state array of length 3. */
  177. q31_t Kp; /**< The proportional gain. */
  178. q31_t Ki; /**< The integral gain. */
  179. q31_t Kd; /**< The derivative gain. */
  180. } riscv_pid_instance_q31;
  181. /**
  182. * @ingroup PID
  183. * @brief Instance structure for the floating-point PID Control.
  184. */
  185. typedef struct
  186. {
  187. float32_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */
  188. float32_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */
  189. float32_t A2; /**< The derived gain, A2 = Kd . */
  190. float32_t state[3]; /**< The state array of length 3. */
  191. float32_t Kp; /**< The proportional gain. */
  192. float32_t Ki; /**< The integral gain. */
  193. float32_t Kd; /**< The derivative gain. */
  194. } riscv_pid_instance_f32;
  195. /**
  196. * @brief Initialization function for the floating-point PID Control.
  197. * @param[in,out] S points to an instance of the PID structure.
  198. * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state.
  199. */
  200. void riscv_pid_init_f32(
  201. riscv_pid_instance_f32 * S,
  202. int32_t resetStateFlag);
  203. /**
  204. * @brief Reset function for the floating-point PID Control.
  205. * @param[in,out] S is an instance of the floating-point PID Control structure
  206. */
  207. void riscv_pid_reset_f32(
  208. riscv_pid_instance_f32 * S);
  209. /**
  210. * @brief Initialization function for the Q31 PID Control.
  211. * @param[in,out] S points to an instance of the Q15 PID structure.
  212. * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state.
  213. */
  214. void riscv_pid_init_q31(
  215. riscv_pid_instance_q31 * S,
  216. int32_t resetStateFlag);
  217. /**
  218. * @brief Reset function for the Q31 PID Control.
  219. * @param[in,out] S points to an instance of the Q31 PID Control structure
  220. */
  221. void riscv_pid_reset_q31(
  222. riscv_pid_instance_q31 * S);
  223. /**
  224. * @brief Initialization function for the Q15 PID Control.
  225. * @param[in,out] S points to an instance of the Q15 PID structure.
  226. * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state.
  227. */
  228. void riscv_pid_init_q15(
  229. riscv_pid_instance_q15 * S,
  230. int32_t resetStateFlag);
  231. /**
  232. * @brief Reset function for the Q15 PID Control.
  233. * @param[in,out] S points to an instance of the q15 PID Control structure
  234. */
  235. void riscv_pid_reset_q15(
  236. riscv_pid_instance_q15 * S);
  237. /**
  238. * @ingroup PID
  239. * @brief Process function for the floating-point PID Control.
  240. * @param[in,out] S is an instance of the floating-point PID Control structure
  241. * @param[in] in input sample to process
  242. * @return processed output sample.
  243. */
  244. __STATIC_FORCEINLINE float32_t riscv_pid_f32(
  245. riscv_pid_instance_f32 * S,
  246. float32_t in)
  247. {
  248. float32_t out;
  249. /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */
  250. out = (S->A0 * in) +
  251. (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]);
  252. /* Update state */
  253. S->state[1] = S->state[0];
  254. S->state[0] = in;
  255. S->state[2] = out;
  256. /* return to application */
  257. return (out);
  258. }
  259. /**
  260. @ingroup PID
  261. @brief Process function for the Q31 PID Control.
  262. @param[in,out] S points to an instance of the Q31 PID Control structure
  263. @param[in] in input sample to process
  264. @return processed output sample.
  265. \par Scaling and Overflow Behavior
  266. The function is implemented using an internal 64-bit accumulator.
  267. The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit.
  268. Thus, if the accumulator result overflows it wraps around rather than clip.
  269. In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions.
  270. After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format.
  271. */
  272. __STATIC_FORCEINLINE q31_t riscv_pid_q31(
  273. riscv_pid_instance_q31 * S,
  274. q31_t in)
  275. {
  276. q63_t acc;
  277. q31_t out;
  278. /* acc = A0 * x[n] */
  279. acc = (q63_t) S->A0 * in;
  280. /* acc += A1 * x[n-1] */
  281. acc += (q63_t) S->A1 * S->state[0];
  282. /* acc += A2 * x[n-2] */
  283. acc += (q63_t) S->A2 * S->state[1];
  284. /* convert output to 1.31 format to add y[n-1] */
  285. out = (q31_t) (acc >> 31U);
  286. /* out += y[n-1] */
  287. out += S->state[2];
  288. /* Update state */
  289. S->state[1] = S->state[0];
  290. S->state[0] = in;
  291. S->state[2] = out;
  292. /* return to application */
  293. return (out);
  294. }
  295. /**
  296. @ingroup PID
  297. @brief Process function for the Q15 PID Control.
  298. @param[in,out] S points to an instance of the Q15 PID Control structure
  299. @param[in] in input sample to process
  300. @return processed output sample.
  301. \par Scaling and Overflow Behavior
  302. The function is implemented using a 64-bit internal accumulator.
  303. Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result.
  304. The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format.
  305. There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved.
  306. After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits.
  307. Lastly, the accumulator is saturated to yield a result in 1.15 format.
  308. */
  309. __STATIC_FORCEINLINE q15_t riscv_pid_q15(
  310. riscv_pid_instance_q15 * S,
  311. q15_t in)
  312. {
  313. q63_t acc;
  314. q15_t out;
  315. #if defined (RISCV_MATH_DSP)
  316. /* Implementation of PID controller */
  317. /* acc = A0 * x[n] */
  318. acc = (q31_t) __SMUAD((uint32_t)S->A0, (uint32_t)in);
  319. /* acc += A1 * x[n-1] + A2 * x[n-2] */
  320. acc = (q63_t)__SMLALD((uint32_t)S->A1, (uint32_t)read_q15x2 (S->state), (uint64_t)acc);
  321. #else
  322. /* acc = A0 * x[n] */
  323. acc = ((q31_t) S->A0) * in;
  324. /* acc += A1 * x[n-1] + A2 * x[n-2] */
  325. acc += (q31_t) S->A1 * S->state[0];
  326. acc += (q31_t) S->A2 * S->state[1];
  327. #endif
  328. asm volatile("nop");
  329. /* acc += y[n-1] */
  330. acc += (q31_t) S->state[2] << 15;
  331. /* saturate the output */
  332. out = (q15_t) (__SSAT((q31_t)(acc >> 15), 16));
  333. /* Update state */
  334. S->state[1] = S->state[0];
  335. S->state[0] = in;
  336. S->state[2] = out;
  337. /* return to application */
  338. return (out);
  339. }
  340. /**
  341. * @ingroup groupController
  342. */
  343. /**
  344. * @defgroup park Vector Park Transform
  345. *
  346. * Forward Park transform converts the input two-coordinate vector to flux and torque components.
  347. * The Park transform can be used to realize the transformation of the <code>Ialpha</code> and the <code>Ibeta</code> currents
  348. * from the stationary to the moving reference frame and control the spatial relationship between
  349. * the stator vector current and rotor flux vector.
  350. * If we consider the d axis aligned with the rotor flux, the diagram below shows the
  351. * current vector and the relationship from the two reference frames:
  352. * \image html park.png "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame"
  353. *
  354. * The function operates on a single sample of data and each call to the function returns the processed output.
  355. * The library provides separate functions for Q31 and floating-point data types.
  356. * \par Algorithm
  357. * \image html parkFormula.png
  358. * where <code>Ialpha</code> and <code>Ibeta</code> are the stator vector components,
  359. * <code>pId</code> and <code>pIq</code> are rotor vector components and <code>cosVal</code> and <code>sinVal</code> are the
  360. * cosine and sine values of theta (rotor flux position).
  361. * \par Fixed-Point Behavior
  362. * Care must be taken when using the Q31 version of the Park transform.
  363. * In particular, the overflow and saturation behavior of the accumulator used must be considered.
  364. * Refer to the function specific documentation below for usage guidelines.
  365. */
  366. /**
  367. * @ingroup park
  368. * @brief Floating-point Park transform
  369. * @param[in] Ialpha input two-phase vector coordinate alpha
  370. * @param[in] Ibeta input two-phase vector coordinate beta
  371. * @param[out] pId points to output rotor reference frame d
  372. * @param[out] pIq points to output rotor reference frame q
  373. * @param[in] sinVal sine value of rotation angle theta
  374. * @param[in] cosVal cosine value of rotation angle theta
  375. *
  376. * The function implements the forward Park transform.
  377. *
  378. */
  379. __STATIC_FORCEINLINE void riscv_park_f32(
  380. float32_t Ialpha,
  381. float32_t Ibeta,
  382. float32_t * pId,
  383. float32_t * pIq,
  384. float32_t sinVal,
  385. float32_t cosVal)
  386. {
  387. /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */
  388. *pId = Ialpha * cosVal + Ibeta * sinVal;
  389. /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */
  390. *pIq = -Ialpha * sinVal + Ibeta * cosVal;
  391. }
  392. /**
  393. @ingroup park
  394. @brief Park transform for Q31 version
  395. @param[in] Ialpha input two-phase vector coordinate alpha
  396. @param[in] Ibeta input two-phase vector coordinate beta
  397. @param[out] pId points to output rotor reference frame d
  398. @param[out] pIq points to output rotor reference frame q
  399. @param[in] sinVal sine value of rotation angle theta
  400. @param[in] cosVal cosine value of rotation angle theta
  401. \par Scaling and Overflow Behavior
  402. The function is implemented using an internal 32-bit accumulator.
  403. The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
  404. There is saturation on the addition and subtraction, hence there is no risk of overflow.
  405. */
  406. __STATIC_FORCEINLINE void riscv_park_q31(
  407. q31_t Ialpha,
  408. q31_t Ibeta,
  409. q31_t * pId,
  410. q31_t * pIq,
  411. q31_t sinVal,
  412. q31_t cosVal)
  413. {
  414. q31_t product1, product2; /* Temporary variables used to store intermediate results */
  415. q31_t product3, product4; /* Temporary variables used to store intermediate results */
  416. /* Intermediate product is calculated by (Ialpha * cosVal) */
  417. product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31);
  418. /* Intermediate product is calculated by (Ibeta * sinVal) */
  419. product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31);
  420. /* Intermediate product is calculated by (Ialpha * sinVal) */
  421. product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31);
  422. /* Intermediate product is calculated by (Ibeta * cosVal) */
  423. product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31);
  424. /* Calculate pId by adding the two intermediate products 1 and 2 */
  425. *pId = __QADD(product1, product2);
  426. /* Calculate pIq by subtracting the two intermediate products 3 from 4 */
  427. *pIq = __QSUB(product4, product3);
  428. }
  429. /**
  430. * @ingroup groupController
  431. */
  432. /**
  433. * @defgroup inv_park Vector Inverse Park transform
  434. * Inverse Park transform converts the input flux and torque components to two-coordinate vector.
  435. *
  436. * The function operates on a single sample of data and each call to the function returns the processed output.
  437. * The library provides separate functions for Q31 and floating-point data types.
  438. * \par Algorithm
  439. * \image html parkInvFormula.png
  440. * where <code>pIalpha</code> and <code>pIbeta</code> are the stator vector components,
  441. * <code>Id</code> and <code>Iq</code> are rotor vector components and <code>cosVal</code> and <code>sinVal</code> are the
  442. * cosine and sine values of theta (rotor flux position).
  443. * \par Fixed-Point Behavior
  444. * Care must be taken when using the Q31 version of the Park transform.
  445. * In particular, the overflow and saturation behavior of the accumulator used must be considered.
  446. * Refer to the function specific documentation below for usage guidelines.
  447. */
  448. /**
  449. * @ingroup inv_park
  450. * @brief Floating-point Inverse Park transform
  451. * @param[in] Id input coordinate of rotor reference frame d
  452. * @param[in] Iq input coordinate of rotor reference frame q
  453. * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha
  454. * @param[out] pIbeta points to output two-phase orthogonal vector axis beta
  455. * @param[in] sinVal sine value of rotation angle theta
  456. * @param[in] cosVal cosine value of rotation angle theta
  457. */
  458. __STATIC_FORCEINLINE void riscv_inv_park_f32(
  459. float32_t Id,
  460. float32_t Iq,
  461. float32_t * pIalpha,
  462. float32_t * pIbeta,
  463. float32_t sinVal,
  464. float32_t cosVal)
  465. {
  466. /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */
  467. *pIalpha = Id * cosVal - Iq * sinVal;
  468. /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */
  469. *pIbeta = Id * sinVal + Iq * cosVal;
  470. }
  471. /**
  472. @ingroup inv_park
  473. @brief Inverse Park transform for Q31 version
  474. @param[in] Id input coordinate of rotor reference frame d
  475. @param[in] Iq input coordinate of rotor reference frame q
  476. @param[out] pIalpha points to output two-phase orthogonal vector axis alpha
  477. @param[out] pIbeta points to output two-phase orthogonal vector axis beta
  478. @param[in] sinVal sine value of rotation angle theta
  479. @param[in] cosVal cosine value of rotation angle theta
  480. @par Scaling and Overflow Behavior
  481. The function is implemented using an internal 32-bit accumulator.
  482. The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
  483. There is saturation on the addition, hence there is no risk of overflow.
  484. */
  485. __STATIC_FORCEINLINE void riscv_inv_park_q31(
  486. q31_t Id,
  487. q31_t Iq,
  488. q31_t * pIalpha,
  489. q31_t * pIbeta,
  490. q31_t sinVal,
  491. q31_t cosVal)
  492. {
  493. q31_t product1, product2; /* Temporary variables used to store intermediate results */
  494. q31_t product3, product4; /* Temporary variables used to store intermediate results */
  495. /* Intermediate product is calculated by (Id * cosVal) */
  496. product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31);
  497. /* Intermediate product is calculated by (Iq * sinVal) */
  498. product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31);
  499. /* Intermediate product is calculated by (Id * sinVal) */
  500. product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31);
  501. /* Intermediate product is calculated by (Iq * cosVal) */
  502. product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31);
  503. /* Calculate pIalpha by using the two intermediate products 1 and 2 */
  504. *pIalpha = __QSUB(product1, product2);
  505. /* Calculate pIbeta by using the two intermediate products 3 and 4 */
  506. *pIbeta = __QADD(product4, product3);
  507. }
  508. /**
  509. * @ingroup groupController
  510. */
  511. /**
  512. * @defgroup clarke Vector Clarke Transform
  513. * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector.
  514. * Generally the Clarke transform uses three-phase currents <code>Ia, Ib and Ic</code> to calculate currents
  515. * in the two-phase orthogonal stator axis <code>Ialpha</code> and <code>Ibeta</code>.
  516. * When <code>Ialpha</code> is superposed with <code>Ia</code> as shown in the figure below
  517. * \image html clarke.png Stator current space vector and its components in (a,b).
  518. * and <code>Ia + Ib + Ic = 0</code>, in this condition <code>Ialpha</code> and <code>Ibeta</code>
  519. * can be calculated using only <code>Ia</code> and <code>Ib</code>.
  520. *
  521. * The function operates on a single sample of data and each call to the function returns the processed output.
  522. * The library provides separate functions for Q31 and floating-point data types.
  523. * \par Algorithm
  524. * \image html clarkeFormula.png
  525. * where <code>Ia</code> and <code>Ib</code> are the instantaneous stator phases and
  526. * <code>pIalpha</code> and <code>pIbeta</code> are the two coordinates of time invariant vector.
  527. * \par Fixed-Point Behavior
  528. * Care must be taken when using the Q31 version of the Clarke transform.
  529. * In particular, the overflow and saturation behavior of the accumulator used must be considered.
  530. * Refer to the function specific documentation below for usage guidelines.
  531. */
  532. /**
  533. *
  534. * @ingroup clarke
  535. * @brief Floating-point Clarke transform
  536. * @param[in] Ia input three-phase coordinate <code>a</code>
  537. * @param[in] Ib input three-phase coordinate <code>b</code>
  538. * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha
  539. * @param[out] pIbeta points to output two-phase orthogonal vector axis beta
  540. */
  541. __STATIC_FORCEINLINE void riscv_clarke_f32(
  542. float32_t Ia,
  543. float32_t Ib,
  544. float32_t * pIalpha,
  545. float32_t * pIbeta)
  546. {
  547. /* Calculate pIalpha using the equation, pIalpha = Ia */
  548. *pIalpha = Ia;
  549. /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */
  550. *pIbeta = (0.57735026919f * Ia + 1.15470053838f * Ib);
  551. }
  552. /**
  553. @ingroup clarke
  554. @brief Clarke transform for Q31 version
  555. @param[in] Ia input three-phase coordinate <code>a</code>
  556. @param[in] Ib input three-phase coordinate <code>b</code>
  557. @param[out] pIalpha points to output two-phase orthogonal vector axis alpha
  558. @param[out] pIbeta points to output two-phase orthogonal vector axis beta
  559. \par Scaling and Overflow Behavior
  560. The function is implemented using an internal 32-bit accumulator.
  561. The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
  562. There is saturation on the addition, hence there is no risk of overflow.
  563. */
  564. __STATIC_FORCEINLINE void riscv_clarke_q31(
  565. q31_t Ia,
  566. q31_t Ib,
  567. q31_t * pIalpha,
  568. q31_t * pIbeta)
  569. {
  570. q31_t product1, product2; /* Temporary variables used to store intermediate results */
  571. /* Calculating pIalpha from Ia by equation pIalpha = Ia */
  572. *pIalpha = Ia;
  573. /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */
  574. product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30);
  575. /* Intermediate product is calculated by (2/sqrt(3) * Ib) */
  576. product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30);
  577. /* pIbeta is calculated by adding the intermediate products */
  578. *pIbeta = __QADD(product1, product2);
  579. }
  580. /**
  581. * @ingroup groupController
  582. */
  583. /**
  584. * @defgroup inv_clarke Vector Inverse Clarke Transform
  585. * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases.
  586. *
  587. * The function operates on a single sample of data and each call to the function returns the processed output.
  588. * The library provides separate functions for Q31 and floating-point data types.
  589. * \par Algorithm
  590. * \image html clarkeInvFormula.png
  591. * where <code>pIa</code> and <code>pIb</code> are the instantaneous stator phases and
  592. * <code>Ialpha</code> and <code>Ibeta</code> are the two coordinates of time invariant vector.
  593. * \par Fixed-Point Behavior
  594. * Care must be taken when using the Q31 version of the Clarke transform.
  595. * In particular, the overflow and saturation behavior of the accumulator used must be considered.
  596. * Refer to the function specific documentation below for usage guidelines.
  597. */
  598. /**
  599. * @ingroup inv_clarke
  600. * @brief Floating-point Inverse Clarke transform
  601. * @param[in] Ialpha input two-phase orthogonal vector axis alpha
  602. * @param[in] Ibeta input two-phase orthogonal vector axis beta
  603. * @param[out] pIa points to output three-phase coordinate <code>a</code>
  604. * @param[out] pIb points to output three-phase coordinate <code>b</code>
  605. */
  606. __STATIC_FORCEINLINE void riscv_inv_clarke_f32(
  607. float32_t Ialpha,
  608. float32_t Ibeta,
  609. float32_t * pIa,
  610. float32_t * pIb)
  611. {
  612. /* Calculating pIa from Ialpha by equation pIa = Ialpha */
  613. *pIa = Ialpha;
  614. /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */
  615. *pIb = -0.5f * Ialpha + 0.8660254039f * Ibeta;
  616. }
  617. /**
  618. @ingroup inv_clarke
  619. @brief Inverse Clarke transform for Q31 version
  620. @param[in] Ialpha input two-phase orthogonal vector axis alpha
  621. @param[in] Ibeta input two-phase orthogonal vector axis beta
  622. @param[out] pIa points to output three-phase coordinate <code>a</code>
  623. @param[out] pIb points to output three-phase coordinate <code>b</code>
  624. \par Scaling and Overflow Behavior
  625. The function is implemented using an internal 32-bit accumulator.
  626. The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
  627. There is saturation on the subtraction, hence there is no risk of overflow.
  628. */
  629. __STATIC_FORCEINLINE void riscv_inv_clarke_q31(
  630. q31_t Ialpha,
  631. q31_t Ibeta,
  632. q31_t * pIa,
  633. q31_t * pIb)
  634. {
  635. q31_t product1, product2; /* Temporary variables used to store intermediate results */
  636. /* Calculating pIa from Ialpha by equation pIa = Ialpha */
  637. *pIa = Ialpha;
  638. /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */
  639. product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31);
  640. /* Intermediate product is calculated by (1/sqrt(3) * pIb) */
  641. product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31);
  642. /* pIb is calculated by subtracting the products */
  643. *pIb = __QSUB(product2, product1);
  644. }
  645. #ifdef __cplusplus
  646. }
  647. #endif
  648. #endif /* ifndef _CONTROLLER_FUNCTIONS_H_ */