mirror of
				https://github.com/IcedRooibos/py32f0-template.git
				synced 2025-10-31 09:52:05 -07:00 
			
		
		
		
	
		
			
				
	
	
		
			792 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			792 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /******************************************************************************
 | |
|  * @file     controller_functions.h
 | |
|  * @brief    Public header file for CMSIS DSP Library
 | |
|  * @version  V1.10.0
 | |
|  * @date     08 July 2021
 | |
|  * Target Processor: Cortex-M and Cortex-A cores
 | |
|  ******************************************************************************/
 | |
| /*
 | |
|  * Copyright (c) 2010-2020 Arm Limited or its affiliates. All rights reserved.
 | |
|  *
 | |
|  * SPDX-License-Identifier: Apache-2.0
 | |
|  *
 | |
|  * Licensed under the Apache License, Version 2.0 (the License); you may
 | |
|  * not use this file except in compliance with the License.
 | |
|  * You may obtain a copy of the License at
 | |
|  *
 | |
|  * www.apache.org/licenses/LICENSE-2.0
 | |
|  *
 | |
|  * Unless required by applicable law or agreed to in writing, software
 | |
|  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
 | |
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
|  * See the License for the specific language governing permissions and
 | |
|  * limitations under the License.
 | |
|  */
 | |
| 
 | |
|  
 | |
| #ifndef _CONTROLLER_FUNCTIONS_H_
 | |
| #define _CONTROLLER_FUNCTIONS_H_
 | |
| 
 | |
| #include "arm_math_types.h"
 | |
| #include "arm_math_memory.h"
 | |
| 
 | |
| #include "dsp/none.h"
 | |
| #include "dsp/utils.h"
 | |
| 
 | |
| #ifdef   __cplusplus
 | |
| extern "C"
 | |
| {
 | |
| #endif
 | |
| 
 | |
|   /**
 | |
|    * @brief Macros required for SINE and COSINE Controller functions
 | |
|    */
 | |
| 
 | |
| #define CONTROLLER_Q31_SHIFT  (32 - 9)
 | |
|   /* 1.31(q31) Fixed value of 2/360 */
 | |
|   /* -1 to +1 is divided into 360 values so total spacing is (2/360) */
 | |
| #define INPUT_SPACING         0xB60B61
 | |
|   
 | |
| /**
 | |
|  * @defgroup groupController Controller Functions
 | |
|  */
 | |
| 
 | |
| 
 | |
|  /**
 | |
|    * @ingroup groupController
 | |
|    */
 | |
| 
 | |
|   /**
 | |
|    * @addtogroup SinCos
 | |
|    * @{
 | |
|    */
 | |
| 
 | |
| /**
 | |
|    * @brief  Floating-point sin_cos function.
 | |
|    * @param[in]  theta   input value in degrees
 | |
|    * @param[out] pSinVal  points to the processed sine output.
 | |
|    * @param[out] pCosVal  points to the processed cos output.
 | |
|    */
 | |
|   void arm_sin_cos_f32(
 | |
|         float32_t theta,
 | |
|         float32_t * pSinVal,
 | |
|         float32_t * pCosVal);
 | |
| 
 | |
| 
 | |
|   /**
 | |
|    * @brief  Q31 sin_cos function.
 | |
|    * @param[in]  theta    scaled input value in degrees
 | |
|    * @param[out] pSinVal  points to the processed sine output.
 | |
|    * @param[out] pCosVal  points to the processed cosine output.
 | |
|    */
 | |
|   void arm_sin_cos_q31(
 | |
|         q31_t theta,
 | |
|         q31_t * pSinVal,
 | |
|         q31_t * pCosVal);
 | |
| 
 | |
|   /**
 | |
|    * @} end of SinCos group
 | |
|    */
 | |
| 
 | |
|  /**
 | |
|    * @ingroup groupController
 | |
|    */
 | |
| 
 | |
| /**
 | |
|    * @defgroup PID PID Motor Control
 | |
|    *
 | |
|    * A Proportional Integral Derivative (PID) controller is a generic feedback control
 | |
|    * loop mechanism widely used in industrial control systems.
 | |
|    * A PID controller is the most commonly used type of feedback controller.
 | |
|    *
 | |
|    * This set of functions implements (PID) controllers
 | |
|    * for Q15, Q31, and floating-point data types.  The functions operate on a single sample
 | |
|    * of data and each call to the function returns a single processed value.
 | |
|    * <code>S</code> points to an instance of the PID control data structure.  <code>in</code>
 | |
|    * is the input sample value. The functions return the output value.
 | |
|    *
 | |
|    * \par Algorithm:
 | |
|    * <pre>
 | |
|    *    y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
 | |
|    *    A0 = Kp + Ki + Kd
 | |
|    *    A1 = (-Kp ) - (2 * Kd )
 | |
|    *    A2 = Kd
 | |
|    * </pre>
 | |
|    *
 | |
|    * \par
 | |
|    * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant
 | |
|    *
 | |
|    * \par
 | |
|    * \image html PID.gif "Proportional Integral Derivative Controller"
 | |
|    *
 | |
|    * \par
 | |
|    * The PID controller calculates an "error" value as the difference between
 | |
|    * the measured output and the reference input.
 | |
|    * The controller attempts to minimize the error by adjusting the process control inputs.
 | |
|    * The proportional value determines the reaction to the current error,
 | |
|    * the integral value determines the reaction based on the sum of recent errors,
 | |
|    * and the derivative value determines the reaction based on the rate at which the error has been changing.
 | |
|    *
 | |
|    * \par Instance Structure
 | |
|    * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure.
 | |
|    * A separate instance structure must be defined for each PID Controller.
 | |
|    * There are separate instance structure declarations for each of the 3 supported data types.
 | |
|    *
 | |
|    * \par Reset Functions
 | |
|    * There is also an associated reset function for each data type which clears the state array.
 | |
|    *
 | |
|    * \par Initialization Functions
 | |
|    * There is also an associated initialization function for each data type.
 | |
|    * The initialization function performs the following operations:
 | |
|    * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains.
 | |
|    * - Zeros out the values in the state buffer.
 | |
|    *
 | |
|    * \par
 | |
|    * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function.
 | |
|    *
 | |
|    * \par Fixed-Point Behavior
 | |
|    * Care must be taken when using the fixed-point versions of the PID Controller functions.
 | |
|    * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered.
 | |
|    * Refer to the function specific documentation below for usage guidelines.
 | |
|    */
 | |
| 
 | |
| 
 | |
|   /**
 | |
|    * @brief Instance structure for the Q15 PID Control.
 | |
|    */
 | |
|   typedef struct
 | |
|   {
 | |
|           q15_t A0;           /**< The derived gain, A0 = Kp + Ki + Kd . */
 | |
| #if !defined (ARM_MATH_DSP)
 | |
|           q15_t A1;           /**< The derived gain A1 = -Kp - 2Kd */
 | |
|           q15_t A2;           /**< The derived gain A1 = Kd. */
 | |
| #else
 | |
|           q31_t A1;           /**< The derived gain A1 = -Kp - 2Kd | Kd.*/
 | |
| #endif
 | |
|           q15_t state[3];     /**< The state array of length 3. */
 | |
|           q15_t Kp;           /**< The proportional gain. */
 | |
|           q15_t Ki;           /**< The integral gain. */
 | |
|           q15_t Kd;           /**< The derivative gain. */
 | |
|   } arm_pid_instance_q15;
 | |
| 
 | |
|   /**
 | |
|    * @brief Instance structure for the Q31 PID Control.
 | |
|    */
 | |
|   typedef struct
 | |
|   {
 | |
|           q31_t A0;            /**< The derived gain, A0 = Kp + Ki + Kd . */
 | |
|           q31_t A1;            /**< The derived gain, A1 = -Kp - 2Kd. */
 | |
|           q31_t A2;            /**< The derived gain, A2 = Kd . */
 | |
|           q31_t state[3];      /**< The state array of length 3. */
 | |
|           q31_t Kp;            /**< The proportional gain. */
 | |
|           q31_t Ki;            /**< The integral gain. */
 | |
|           q31_t Kd;            /**< The derivative gain. */
 | |
|   } arm_pid_instance_q31;
 | |
| 
 | |
|   /**
 | |
|    * @brief Instance structure for the floating-point PID Control.
 | |
|    */
 | |
|   typedef struct
 | |
|   {
 | |
|           float32_t A0;          /**< The derived gain, A0 = Kp + Ki + Kd . */
 | |
|           float32_t A1;          /**< The derived gain, A1 = -Kp - 2Kd. */
 | |
|           float32_t A2;          /**< The derived gain, A2 = Kd . */
 | |
|           float32_t state[3];    /**< The state array of length 3. */
 | |
|           float32_t Kp;          /**< The proportional gain. */
 | |
|           float32_t Ki;          /**< The integral gain. */
 | |
|           float32_t Kd;          /**< The derivative gain. */
 | |
|   } arm_pid_instance_f32;
 | |
| 
 | |
| 
 | |
| 
 | |
|   /**
 | |
|    * @brief  Initialization function for the floating-point PID Control.
 | |
|    * @param[in,out] S               points to an instance of the PID structure.
 | |
|    * @param[in]     resetStateFlag  flag to reset the state. 0 = no change in state 1 = reset the state.
 | |
|    */
 | |
|   void arm_pid_init_f32(
 | |
|         arm_pid_instance_f32 * S,
 | |
|         int32_t resetStateFlag);
 | |
| 
 | |
| 
 | |
|   /**
 | |
|    * @brief  Reset function for the floating-point PID Control.
 | |
|    * @param[in,out] S  is an instance of the floating-point PID Control structure
 | |
|    */
 | |
|   void arm_pid_reset_f32(
 | |
|         arm_pid_instance_f32 * S);
 | |
| 
 | |
| 
 | |
|   /**
 | |
|    * @brief  Initialization function for the Q31 PID Control.
 | |
|    * @param[in,out] S               points to an instance of the Q15 PID structure.
 | |
|    * @param[in]     resetStateFlag  flag to reset the state. 0 = no change in state 1 = reset the state.
 | |
|    */
 | |
|   void arm_pid_init_q31(
 | |
|         arm_pid_instance_q31 * S,
 | |
|         int32_t resetStateFlag);
 | |
| 
 | |
| 
 | |
|   /**
 | |
|    * @brief  Reset function for the Q31 PID Control.
 | |
|    * @param[in,out] S   points to an instance of the Q31 PID Control structure
 | |
|    */
 | |
| 
 | |
|   void arm_pid_reset_q31(
 | |
|         arm_pid_instance_q31 * S);
 | |
| 
 | |
| 
 | |
|   /**
 | |
|    * @brief  Initialization function for the Q15 PID Control.
 | |
|    * @param[in,out] S               points to an instance of the Q15 PID structure.
 | |
|    * @param[in]     resetStateFlag  flag to reset the state. 0 = no change in state 1 = reset the state.
 | |
|    */
 | |
|   void arm_pid_init_q15(
 | |
|         arm_pid_instance_q15 * S,
 | |
|         int32_t resetStateFlag);
 | |
| 
 | |
| 
 | |
|   /**
 | |
|    * @brief  Reset function for the Q15 PID Control.
 | |
|    * @param[in,out] S  points to an instance of the q15 PID Control structure
 | |
|    */
 | |
|   void arm_pid_reset_q15(
 | |
|         arm_pid_instance_q15 * S);
 | |
| 
 | |
| 
 | |
| 
 | |
|   /**
 | |
|    * @addtogroup PID
 | |
|    * @{
 | |
|    */
 | |
| 
 | |
|   /**
 | |
|    * @brief         Process function for the floating-point PID Control.
 | |
|    * @param[in,out] S   is an instance of the floating-point PID Control structure
 | |
|    * @param[in]     in  input sample to process
 | |
|    * @return        processed output sample.
 | |
|    */
 | |
|   __STATIC_FORCEINLINE float32_t arm_pid_f32(
 | |
|   arm_pid_instance_f32 * S,
 | |
|   float32_t in)
 | |
|   {
 | |
|     float32_t out;
 | |
| 
 | |
|     /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]  */
 | |
|     out = (S->A0 * in) +
 | |
|       (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]);
 | |
| 
 | |
|     /* Update state */
 | |
|     S->state[1] = S->state[0];
 | |
|     S->state[0] = in;
 | |
|     S->state[2] = out;
 | |
| 
 | |
|     /* return to application */
 | |
|     return (out);
 | |
| 
 | |
|   }
 | |
| 
 | |
| /**
 | |
|   @brief         Process function for the Q31 PID Control.
 | |
|   @param[in,out] S  points to an instance of the Q31 PID Control structure
 | |
|   @param[in]     in  input sample to process
 | |
|   @return        processed output sample.
 | |
| 
 | |
|   \par Scaling and Overflow Behavior
 | |
|          The function is implemented using an internal 64-bit accumulator.
 | |
|          The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit.
 | |
|          Thus, if the accumulator result overflows it wraps around rather than clip.
 | |
|          In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions.
 | |
|          After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format.
 | |
|  */
 | |
| __STATIC_FORCEINLINE q31_t arm_pid_q31(
 | |
|   arm_pid_instance_q31 * S,
 | |
|   q31_t in)
 | |
|   {
 | |
|     q63_t acc;
 | |
|     q31_t out;
 | |
| 
 | |
|     /* acc = A0 * x[n]  */
 | |
|     acc = (q63_t) S->A0 * in;
 | |
| 
 | |
|     /* acc += A1 * x[n-1] */
 | |
|     acc += (q63_t) S->A1 * S->state[0];
 | |
| 
 | |
|     /* acc += A2 * x[n-2]  */
 | |
|     acc += (q63_t) S->A2 * S->state[1];
 | |
| 
 | |
|     /* convert output to 1.31 format to add y[n-1] */
 | |
|     out = (q31_t) (acc >> 31U);
 | |
| 
 | |
|     /* out += y[n-1] */
 | |
|     out += S->state[2];
 | |
| 
 | |
|     /* Update state */
 | |
|     S->state[1] = S->state[0];
 | |
|     S->state[0] = in;
 | |
|     S->state[2] = out;
 | |
| 
 | |
|     /* return to application */
 | |
|     return (out);
 | |
|   }
 | |
| 
 | |
| 
 | |
| /**
 | |
|   @brief         Process function for the Q15 PID Control.
 | |
|   @param[in,out] S   points to an instance of the Q15 PID Control structure
 | |
|   @param[in]     in  input sample to process
 | |
|   @return        processed output sample.
 | |
| 
 | |
|   \par Scaling and Overflow Behavior
 | |
|          The function is implemented using a 64-bit internal accumulator.
 | |
|          Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result.
 | |
|          The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format.
 | |
|          There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved.
 | |
|          After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits.
 | |
|          Lastly, the accumulator is saturated to yield a result in 1.15 format.
 | |
|  */
 | |
| __STATIC_FORCEINLINE q15_t arm_pid_q15(
 | |
|   arm_pid_instance_q15 * S,
 | |
|   q15_t in)
 | |
|   {
 | |
|     q63_t acc;
 | |
|     q15_t out;
 | |
| 
 | |
| #if defined (ARM_MATH_DSP)
 | |
|     /* Implementation of PID controller */
 | |
| 
 | |
|     /* acc = A0 * x[n]  */
 | |
|     acc = (q31_t) __SMUAD((uint32_t)S->A0, (uint32_t)in);
 | |
| 
 | |
|     /* acc += A1 * x[n-1] + A2 * x[n-2]  */
 | |
|     acc = (q63_t)__SMLALD((uint32_t)S->A1, (uint32_t)read_q15x2 (S->state), (uint64_t)acc);
 | |
| #else
 | |
|     /* acc = A0 * x[n]  */
 | |
|     acc = ((q31_t) S->A0) * in;
 | |
| 
 | |
|     /* acc += A1 * x[n-1] + A2 * x[n-2]  */
 | |
|     acc += (q31_t) S->A1 * S->state[0];
 | |
|     acc += (q31_t) S->A2 * S->state[1];
 | |
| #endif
 | |
| 
 | |
|     /* acc += y[n-1] */
 | |
|     acc += (q31_t) S->state[2] << 15;
 | |
| 
 | |
|     /* saturate the output */
 | |
|     out = (q15_t) (__SSAT((q31_t)(acc >> 15), 16));
 | |
| 
 | |
|     /* Update state */
 | |
|     S->state[1] = S->state[0];
 | |
|     S->state[0] = in;
 | |
|     S->state[2] = out;
 | |
| 
 | |
|     /* return to application */
 | |
|     return (out);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @} end of PID group
 | |
|    */
 | |
| 
 | |
|   /**
 | |
|    * @ingroup groupController
 | |
|    */
 | |
| 
 | |
|   /**
 | |
|    * @defgroup park Vector Park Transform
 | |
|    *
 | |
|    * Forward Park transform converts the input two-coordinate vector to flux and torque components.
 | |
|    * The Park transform can be used to realize the transformation of the <code>Ialpha</code> and the <code>Ibeta</code> currents
 | |
|    * from the stationary to the moving reference frame and control the spatial relationship between
 | |
|    * the stator vector current and rotor flux vector.
 | |
|    * If we consider the d axis aligned with the rotor flux, the diagram below shows the
 | |
|    * current vector and the relationship from the two reference frames:
 | |
|    * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame"
 | |
|    *
 | |
|    * The function operates on a single sample of data and each call to the function returns the processed output.
 | |
|    * The library provides separate functions for Q31 and floating-point data types.
 | |
|    * \par Algorithm
 | |
|    * \image html parkFormula.gif
 | |
|    * where <code>Ialpha</code> and <code>Ibeta</code> are the stator vector components,
 | |
|    * <code>pId</code> and <code>pIq</code> are rotor vector components and <code>cosVal</code> and <code>sinVal</code> are the
 | |
|    * cosine and sine values of theta (rotor flux position).
 | |
|    * \par Fixed-Point Behavior
 | |
|    * Care must be taken when using the Q31 version of the Park transform.
 | |
|    * In particular, the overflow and saturation behavior of the accumulator used must be considered.
 | |
|    * Refer to the function specific documentation below for usage guidelines.
 | |
|    */
 | |
| 
 | |
|   /**
 | |
|    * @addtogroup park
 | |
|    * @{
 | |
|    */
 | |
| 
 | |
|   /**
 | |
|    * @brief Floating-point Park transform
 | |
|    * @param[in]  Ialpha  input two-phase vector coordinate alpha
 | |
|    * @param[in]  Ibeta   input two-phase vector coordinate beta
 | |
|    * @param[out] pId     points to output   rotor reference frame d
 | |
|    * @param[out] pIq     points to output   rotor reference frame q
 | |
|    * @param[in]  sinVal  sine value of rotation angle theta
 | |
|    * @param[in]  cosVal  cosine value of rotation angle theta
 | |
|    * @return     none
 | |
|    *
 | |
|    * The function implements the forward Park transform.
 | |
|    *
 | |
|    */
 | |
|   __STATIC_FORCEINLINE void arm_park_f32(
 | |
|   float32_t Ialpha,
 | |
|   float32_t Ibeta,
 | |
|   float32_t * pId,
 | |
|   float32_t * pIq,
 | |
|   float32_t sinVal,
 | |
|   float32_t cosVal)
 | |
|   {
 | |
|     /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */
 | |
|     *pId = Ialpha * cosVal + Ibeta * sinVal;
 | |
| 
 | |
|     /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */
 | |
|     *pIq = -Ialpha * sinVal + Ibeta * cosVal;
 | |
|   }
 | |
| 
 | |
| 
 | |
| /**
 | |
|   @brief  Park transform for Q31 version
 | |
|   @param[in]  Ialpha  input two-phase vector coordinate alpha
 | |
|   @param[in]  Ibeta   input two-phase vector coordinate beta
 | |
|   @param[out] pId     points to output rotor reference frame d
 | |
|   @param[out] pIq     points to output rotor reference frame q
 | |
|   @param[in]  sinVal  sine value of rotation angle theta
 | |
|   @param[in]  cosVal  cosine value of rotation angle theta
 | |
|   @return     none
 | |
| 
 | |
|   \par Scaling and Overflow Behavior
 | |
|          The function is implemented using an internal 32-bit accumulator.
 | |
|          The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
 | |
|          There is saturation on the addition and subtraction, hence there is no risk of overflow.
 | |
|  */
 | |
| __STATIC_FORCEINLINE void arm_park_q31(
 | |
|   q31_t Ialpha,
 | |
|   q31_t Ibeta,
 | |
|   q31_t * pId,
 | |
|   q31_t * pIq,
 | |
|   q31_t sinVal,
 | |
|   q31_t cosVal)
 | |
|   {
 | |
|     q31_t product1, product2;                    /* Temporary variables used to store intermediate results */
 | |
|     q31_t product3, product4;                    /* Temporary variables used to store intermediate results */
 | |
| 
 | |
|     /* Intermediate product is calculated by (Ialpha * cosVal) */
 | |
|     product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31);
 | |
| 
 | |
|     /* Intermediate product is calculated by (Ibeta * sinVal) */
 | |
|     product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31);
 | |
| 
 | |
| 
 | |
|     /* Intermediate product is calculated by (Ialpha * sinVal) */
 | |
|     product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31);
 | |
| 
 | |
|     /* Intermediate product is calculated by (Ibeta * cosVal) */
 | |
|     product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31);
 | |
| 
 | |
|     /* Calculate pId by adding the two intermediate products 1 and 2 */
 | |
|     *pId = __QADD(product1, product2);
 | |
| 
 | |
|     /* Calculate pIq by subtracting the two intermediate products 3 from 4 */
 | |
|     *pIq = __QSUB(product4, product3);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @} end of park group
 | |
|    */
 | |
| 
 | |
| 
 | |
|   /**
 | |
|    * @ingroup groupController
 | |
|    */
 | |
| 
 | |
|   /**
 | |
|    * @defgroup inv_park Vector Inverse Park transform
 | |
|    * Inverse Park transform converts the input flux and torque components to two-coordinate vector.
 | |
|    *
 | |
|    * The function operates on a single sample of data and each call to the function returns the processed output.
 | |
|    * The library provides separate functions for Q31 and floating-point data types.
 | |
|    * \par Algorithm
 | |
|    * \image html parkInvFormula.gif
 | |
|    * where <code>pIalpha</code> and <code>pIbeta</code> are the stator vector components,
 | |
|    * <code>Id</code> and <code>Iq</code> are rotor vector components and <code>cosVal</code> and <code>sinVal</code> are the
 | |
|    * cosine and sine values of theta (rotor flux position).
 | |
|    * \par Fixed-Point Behavior
 | |
|    * Care must be taken when using the Q31 version of the Park transform.
 | |
|    * In particular, the overflow and saturation behavior of the accumulator used must be considered.
 | |
|    * Refer to the function specific documentation below for usage guidelines.
 | |
|    */
 | |
| 
 | |
|   /**
 | |
|    * @addtogroup inv_park
 | |
|    * @{
 | |
|    */
 | |
| 
 | |
|    /**
 | |
|    * @brief  Floating-point Inverse Park transform
 | |
|    * @param[in]  Id       input coordinate of rotor reference frame d
 | |
|    * @param[in]  Iq       input coordinate of rotor reference frame q
 | |
|    * @param[out] pIalpha  points to output two-phase orthogonal vector axis alpha
 | |
|    * @param[out] pIbeta   points to output two-phase orthogonal vector axis beta
 | |
|    * @param[in]  sinVal   sine value of rotation angle theta
 | |
|    * @param[in]  cosVal   cosine value of rotation angle theta
 | |
|    * @return     none
 | |
|    */
 | |
|   __STATIC_FORCEINLINE void arm_inv_park_f32(
 | |
|   float32_t Id,
 | |
|   float32_t Iq,
 | |
|   float32_t * pIalpha,
 | |
|   float32_t * pIbeta,
 | |
|   float32_t sinVal,
 | |
|   float32_t cosVal)
 | |
|   {
 | |
|     /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */
 | |
|     *pIalpha = Id * cosVal - Iq * sinVal;
 | |
| 
 | |
|     /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */
 | |
|     *pIbeta = Id * sinVal + Iq * cosVal;
 | |
|   }
 | |
| 
 | |
| 
 | |
| /**
 | |
|   @brief  Inverse Park transform for   Q31 version
 | |
|   @param[in]  Id       input coordinate of rotor reference frame d
 | |
|   @param[in]  Iq       input coordinate of rotor reference frame q
 | |
|   @param[out] pIalpha  points to output two-phase orthogonal vector axis alpha
 | |
|   @param[out] pIbeta   points to output two-phase orthogonal vector axis beta
 | |
|   @param[in]  sinVal   sine value of rotation angle theta
 | |
|   @param[in]  cosVal   cosine value of rotation angle theta
 | |
|   @return     none
 | |
| 
 | |
|   @par Scaling and Overflow Behavior
 | |
|          The function is implemented using an internal 32-bit accumulator.
 | |
|          The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
 | |
|          There is saturation on the addition, hence there is no risk of overflow.
 | |
|  */
 | |
| __STATIC_FORCEINLINE void arm_inv_park_q31(
 | |
|   q31_t Id,
 | |
|   q31_t Iq,
 | |
|   q31_t * pIalpha,
 | |
|   q31_t * pIbeta,
 | |
|   q31_t sinVal,
 | |
|   q31_t cosVal)
 | |
|   {
 | |
|     q31_t product1, product2;                    /* Temporary variables used to store intermediate results */
 | |
|     q31_t product3, product4;                    /* Temporary variables used to store intermediate results */
 | |
| 
 | |
|     /* Intermediate product is calculated by (Id * cosVal) */
 | |
|     product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31);
 | |
| 
 | |
|     /* Intermediate product is calculated by (Iq * sinVal) */
 | |
|     product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31);
 | |
| 
 | |
| 
 | |
|     /* Intermediate product is calculated by (Id * sinVal) */
 | |
|     product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31);
 | |
| 
 | |
|     /* Intermediate product is calculated by (Iq * cosVal) */
 | |
|     product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31);
 | |
| 
 | |
|     /* Calculate pIalpha by using the two intermediate products 1 and 2 */
 | |
|     *pIalpha = __QSUB(product1, product2);
 | |
| 
 | |
|     /* Calculate pIbeta by using the two intermediate products 3 and 4 */
 | |
|     *pIbeta = __QADD(product4, product3);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @} end of Inverse park group
 | |
|    */
 | |
| 
 | |
| /**
 | |
|    * @ingroup groupController
 | |
|    */
 | |
| 
 | |
|   /**
 | |
|    * @defgroup clarke Vector Clarke Transform
 | |
|    * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector.
 | |
|    * Generally the Clarke transform uses three-phase currents <code>Ia, Ib and Ic</code> to calculate currents
 | |
|    * in the two-phase orthogonal stator axis <code>Ialpha</code> and <code>Ibeta</code>.
 | |
|    * When <code>Ialpha</code> is superposed with <code>Ia</code> as shown in the figure below
 | |
|    * \image html clarke.gif Stator current space vector and its components in (a,b).
 | |
|    * and <code>Ia + Ib + Ic = 0</code>, in this condition <code>Ialpha</code> and <code>Ibeta</code>
 | |
|    * can be calculated using only <code>Ia</code> and <code>Ib</code>.
 | |
|    *
 | |
|    * The function operates on a single sample of data and each call to the function returns the processed output.
 | |
|    * The library provides separate functions for Q31 and floating-point data types.
 | |
|    * \par Algorithm
 | |
|    * \image html clarkeFormula.gif
 | |
|    * where <code>Ia</code> and <code>Ib</code> are the instantaneous stator phases and
 | |
|    * <code>pIalpha</code> and <code>pIbeta</code> are the two coordinates of time invariant vector.
 | |
|    * \par Fixed-Point Behavior
 | |
|    * Care must be taken when using the Q31 version of the Clarke transform.
 | |
|    * In particular, the overflow and saturation behavior of the accumulator used must be considered.
 | |
|    * Refer to the function specific documentation below for usage guidelines.
 | |
|    */
 | |
| 
 | |
|   /**
 | |
|    * @addtogroup clarke
 | |
|    * @{
 | |
|    */
 | |
| 
 | |
|   /**
 | |
|    *
 | |
|    * @brief  Floating-point Clarke transform
 | |
|    * @param[in]  Ia       input three-phase coordinate <code>a</code>
 | |
|    * @param[in]  Ib       input three-phase coordinate <code>b</code>
 | |
|    * @param[out] pIalpha  points to output two-phase orthogonal vector axis alpha
 | |
|    * @param[out] pIbeta   points to output two-phase orthogonal vector axis beta
 | |
|    * @return        none
 | |
|    */
 | |
|   __STATIC_FORCEINLINE void arm_clarke_f32(
 | |
|   float32_t Ia,
 | |
|   float32_t Ib,
 | |
|   float32_t * pIalpha,
 | |
|   float32_t * pIbeta)
 | |
|   {
 | |
|     /* Calculate pIalpha using the equation, pIalpha = Ia */
 | |
|     *pIalpha = Ia;
 | |
| 
 | |
|     /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */
 | |
|     *pIbeta = (0.57735026919f * Ia + 1.15470053838f * Ib);
 | |
|   }
 | |
| 
 | |
| 
 | |
| /**
 | |
|   @brief  Clarke transform for Q31 version
 | |
|   @param[in]  Ia       input three-phase coordinate <code>a</code>
 | |
|   @param[in]  Ib       input three-phase coordinate <code>b</code>
 | |
|   @param[out] pIalpha  points to output two-phase orthogonal vector axis alpha
 | |
|   @param[out] pIbeta   points to output two-phase orthogonal vector axis beta
 | |
|   @return     none
 | |
| 
 | |
|   \par Scaling and Overflow Behavior
 | |
|          The function is implemented using an internal 32-bit accumulator.
 | |
|          The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
 | |
|          There is saturation on the addition, hence there is no risk of overflow.
 | |
|  */
 | |
| __STATIC_FORCEINLINE void arm_clarke_q31(
 | |
|   q31_t Ia,
 | |
|   q31_t Ib,
 | |
|   q31_t * pIalpha,
 | |
|   q31_t * pIbeta)
 | |
|   {
 | |
|     q31_t product1, product2;                    /* Temporary variables used to store intermediate results */
 | |
| 
 | |
|     /* Calculating pIalpha from Ia by equation pIalpha = Ia */
 | |
|     *pIalpha = Ia;
 | |
| 
 | |
|     /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */
 | |
|     product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30);
 | |
| 
 | |
|     /* Intermediate product is calculated by (2/sqrt(3) * Ib) */
 | |
|     product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30);
 | |
| 
 | |
|     /* pIbeta is calculated by adding the intermediate products */
 | |
|     *pIbeta = __QADD(product1, product2);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @} end of clarke group
 | |
|    */
 | |
| 
 | |
| 
 | |
|   /**
 | |
|    * @ingroup groupController
 | |
|    */
 | |
| 
 | |
|   /**
 | |
|    * @defgroup inv_clarke Vector Inverse Clarke Transform
 | |
|    * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases.
 | |
|    *
 | |
|    * The function operates on a single sample of data and each call to the function returns the processed output.
 | |
|    * The library provides separate functions for Q31 and floating-point data types.
 | |
|    * \par Algorithm
 | |
|    * \image html clarkeInvFormula.gif
 | |
|    * where <code>pIa</code> and <code>pIb</code> are the instantaneous stator phases and
 | |
|    * <code>Ialpha</code> and <code>Ibeta</code> are the two coordinates of time invariant vector.
 | |
|    * \par Fixed-Point Behavior
 | |
|    * Care must be taken when using the Q31 version of the Clarke transform.
 | |
|    * In particular, the overflow and saturation behavior of the accumulator used must be considered.
 | |
|    * Refer to the function specific documentation below for usage guidelines.
 | |
|    */
 | |
| 
 | |
|   /**
 | |
|    * @addtogroup inv_clarke
 | |
|    * @{
 | |
|    */
 | |
| 
 | |
|    /**
 | |
|    * @brief  Floating-point Inverse Clarke transform
 | |
|    * @param[in]  Ialpha  input two-phase orthogonal vector axis alpha
 | |
|    * @param[in]  Ibeta   input two-phase orthogonal vector axis beta
 | |
|    * @param[out] pIa     points to output three-phase coordinate <code>a</code>
 | |
|    * @param[out] pIb     points to output three-phase coordinate <code>b</code>
 | |
|    * @return     none
 | |
|    */
 | |
|   __STATIC_FORCEINLINE void arm_inv_clarke_f32(
 | |
|   float32_t Ialpha,
 | |
|   float32_t Ibeta,
 | |
|   float32_t * pIa,
 | |
|   float32_t * pIb)
 | |
|   {
 | |
|     /* Calculating pIa from Ialpha by equation pIa = Ialpha */
 | |
|     *pIa = Ialpha;
 | |
| 
 | |
|     /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */
 | |
|     *pIb = -0.5f * Ialpha + 0.8660254039f * Ibeta;
 | |
|   }
 | |
| 
 | |
| 
 | |
| /**
 | |
|   @brief  Inverse Clarke transform for Q31 version
 | |
|   @param[in]  Ialpha  input two-phase orthogonal vector axis alpha
 | |
|   @param[in]  Ibeta   input two-phase orthogonal vector axis beta
 | |
|   @param[out] pIa     points to output three-phase coordinate <code>a</code>
 | |
|   @param[out] pIb     points to output three-phase coordinate <code>b</code>
 | |
|   @return     none
 | |
| 
 | |
|   \par Scaling and Overflow Behavior
 | |
|          The function is implemented using an internal 32-bit accumulator.
 | |
|          The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
 | |
|          There is saturation on the subtraction, hence there is no risk of overflow.
 | |
|  */
 | |
| __STATIC_FORCEINLINE void arm_inv_clarke_q31(
 | |
|   q31_t Ialpha,
 | |
|   q31_t Ibeta,
 | |
|   q31_t * pIa,
 | |
|   q31_t * pIb)
 | |
|   {
 | |
|     q31_t product1, product2;                    /* Temporary variables used to store intermediate results */
 | |
| 
 | |
|     /* Calculating pIa from Ialpha by equation pIa = Ialpha */
 | |
|     *pIa = Ialpha;
 | |
| 
 | |
|     /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */
 | |
|     product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31);
 | |
| 
 | |
|     /* Intermediate product is calculated by (1/sqrt(3) * pIb) */
 | |
|     product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31);
 | |
| 
 | |
|     /* pIb is calculated by subtracting the products */
 | |
|     *pIb = __QSUB(product2, product1);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @} end of inv_clarke group
 | |
|    */
 | |
| 
 | |
| 
 | |
| 
 | |
|   
 | |
| #ifdef   __cplusplus
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #endif /* ifndef _CONTROLLER_FUNCTIONS_H_ */
 | 
