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