* include/dspb16.h
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you 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
*
* http://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 __INCLUDE_DSPB16_H
#define __INCLUDE_DSPB16_H
* Included Files
****************************************************************************/
#include <nuttx/compiler.h>
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <fixedmath.h>
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_LIBDSP_DEBUG
# ifndef CONFIG_DEBUG_ASSERTIONS
# warning "Need CONFIG_DEBUG_ASSERTIONS to work properly"
# endif
# define LIBDSP_DEBUGASSERT(x) DEBUGASSERT(x)
#else
# undef LIBDSP_DEBUGASSERT
# define LIBDSP_DEBUGASSERT(x)
#endif
#ifndef CONFIG_LIBDSP_PRECISION
# define CONFIG_LIBDSP_PRECISION 0
#endif
#define DIR_NONE_B16 ftob16(0.0f)
#define DIR_CW_B16 ftob16(1.0f)
#define DIR_CCW_B16 ftob16(-1.0f)
#define SQRT3_BY_TWO_B16 ftob16(0.866025f)
#define SQRT3_BY_THREE_B16 ftob16(0.57735f)
#define ONE_BY_SQRT3_B16 ftob16(0.57735f)
#define TWO_BY_SQRT3_B16 ftob16(1.15470f)
#define MOTOR_ANGLE_E_MAX_B16 (b16TWOPI)
#define MOTOR_ANGLE_E_MIN_B16 (0)
#define MOTOR_ANGLE_E_RANGE_B16 (MOTOR_ANGLE_E_MAX_B16 - MOTOR_ANGLE_E_MIN_B16)
#define MOTOR_ANGLE_M_MAX_B16 (b16TWOPI)
#define MOTOR_ANGLE_M_MIN_B16 (0)
#define MOTOR_ANGLE_M_RANGE_B16 (MOTOR_ANGLE_M_MAX_B16 - MOTOR_ANGLE_M_MIN_B16)
* Name: LP_FILTER_B16
*
* Description:
* Simple single-pole digital low pass filter:
* Y(n) = (1-beta)*Y(n-1) + beta*X(n) = (beta * (Y(n-1) - X(n)))
*
* filter - (0.0 - 1.0) where 1.0 gives unfiltered values
* filter = T * (2*PI) * f_c
*
* phase shift = -arctan(f_in/f_c)
* time constant = -T / (ln(1 - filter))
*
* T - period at which the digital filter is being calculated
* f_in - input frequency of the filter
* f_c - cutoff frequency of the filter
*
* REFERENCE: https://www.embeddedrelated.com/showarticle/779.php
*
****************************************************************************/
#define LP_FILTER_B16(val, sample, filter) val -= (b16mulb16(filter, (val - sample)))
* Name: SVM3_BASE_VOLTAGE_GET_B16
*
* Description:
* Get maximum voltage for SVM3 without overmodulation
*
* Notes:
* max possible phase voltage for 3-phase power inverter:
* Vd = (2/3)*Vdc
* max phase reference voltage according to SVM modulation diagram:
* Vrefmax = Vd * cos(30*) = SQRT3_BY_2 * Vd
* which give us:
* Vrefmax = SQRT3_BY_3 * Vdc
*
* Vdc - bus voltage
*
****************************************************************************/
#define SVM3_BASE_VOLTAGE_GET_B16(vbus) (b16mulb16(vbus, SQRT3_BY_THREE_B16))
* Public Types
****************************************************************************/
* Besides angle value it also stores sine and cosine values for given angle.
*/
struct phase_angle_b16_s
{
b16_t angle;
b16_t sin;
b16_t cos;
};
typedef struct phase_angle_b16_s phase_angle_b16_t;
*
* th_el = th_m * pole_pairs
* th_m = th_el/pole_pairs
*
* where:
* th_el - motor electrical angle
* th_m - motor mechanical angle
* pole_pairs - motor pole pairs
*
* NOTE: pole_pairs = poles_total/2
*/
struct motor_angle_b16_s
{
phase_angle_b16_t angle_el;
b16_t anglem;
b16_t one_by_p;
uint8_t p;
int8_t i;
};
struct float_sat_b16_s
{
b16_t min;
b16_t max;
};
typedef struct float_sat_b16_s float_sat_b16_t;
struct pid_controller_b16_s
{
bool aw_en;
bool ireset_en;
bool pisat_en;
bool pidsat_en;
bool _res;
b16_t out;
float_sat_b16_t sat;
b16_t err;
b16_t err_prev;
b16_t KP;
b16_t KI;
b16_t KD;
b16_t part[3];
* 1 - integral part
* 2 - derivative part
*/
b16_t KC;
b16_t aw;
};
typedef struct pid_controller_b16_s pid_controller_b16_t;
struct abc_frame_b16_s
{
b16_t a;
b16_t b;
b16_t c;
};
typedef struct abc_frame_b16_s abc_frame_b16_t;
struct ab_frame_b16_s
{
b16_t a;
b16_t b;
};
typedef struct ab_frame_b16_s ab_frame_b16_t;
struct dq_frame_b16_s
{
b16_t d;
b16_t q;
};
typedef struct dq_frame_b16_s dq_frame_b16_t;
struct svm3_state_b16_s
{
uint8_t sector;
b16_t d_u;
b16_t d_v;
b16_t d_w;
};
struct openloop_data_b16_s
{
b16_t angle;
b16_t per;
};
struct motor_sobserver_b16_s
{
b16_t speed;
b16_t per;
* sets of private data.
*/
void *so;
};
struct motor_aobserver_b16_s
{
b16_t angle;
b16_t per;
* sets of private data.
*/
void *ao;
};
struct motor_sobserver_div_b16_s
{
b16_t angle_diff;
b16_t angle_acc;
b16_t angle_prev;
b16_t one_by_dt;
b16_t cntr;
b16_t samples;
b16_t filter;
};
struct motor_sobserver_pll_b16_s
{
b16_t pll_phase;
b16_t pll_kp;
b16_t pll_ki;
};
struct motor_aobserver_smo_b16_s
{
b16_t k_slide;
b16_t err_max;
b16_t one_by_err_max;
b16_t F;
b16_t G;
b16_t emf_lp_filter1;
b16_t emf_lp_filter2;
ab_frame_b16_t emf;
ab_frame_b16_t emf_f;
ab_frame_b16_t z;
ab_frame_b16_t i_est;
ab_frame_b16_t v_err;
ab_frame_b16_t i_err;
ab_frame_b16_t sign;
};
struct motor_aobserver_nfo_b16_s
{
b16_t x1;
b16_t x2;
};
struct foc_initdata_b16_s
{
b16_t id_kp;
b16_t id_ki;
b16_t iq_kp;
b16_t iq_ki;
};
struct foc_data_b16_s
{
abc_frame_b16_t v_abc;
ab_frame_b16_t v_ab;
dq_frame_b16_t v_dq;
ab_frame_b16_t v_ab_mod;
* magnitude (0.0, 1.0)
*/
abc_frame_b16_t i_abc;
ab_frame_b16_t i_ab;
dq_frame_b16_t i_dq;
dq_frame_b16_t i_dq_err;
dq_frame_b16_t i_dq_ref;
* current controller
*/
pid_controller_b16_t id_pid;
pid_controller_b16_t iq_pid;
b16_t vdq_mag_max;
b16_t vab_mod_scale;
phase_angle_b16_t angle;
};
* This data structure was designed to work with BLDC/PMSM motors,
* but probably can be used to describe different types of motors.
*/
struct motor_phy_params_b16_s
{
uint8_t p;
b16_t flux_link;
b16_t res;
b16_t ind;
b16_t one_by_ind;
b16_t one_by_p;
};
struct pmsm_phy_params_b16_s
{
struct motor_phy_params_b16_s motor;
b16_t iner;
b16_t ind_d;
b16_t ind_q;
b16_t one_by_iner;
b16_t one_by_indd;
b16_t one_by_indq;
};
struct pmsm_model_state_b16_s
{
abc_frame_b16_t i_abc;
ab_frame_b16_t i_ab;
dq_frame_b16_t i_dq;
abc_frame_b16_t v_abc;
ab_frame_b16_t v_ab;
dq_frame_b16_t v_dq;
struct motor_angle_b16_s angle;
b16_t omega_e;
b16_t omega_m;
};
struct pmsm_model_ext_b16_s
{
b16_t load;
};
struct pmsm_model_b16_s
{
struct pmsm_phy_params_b16_s phy;
struct pmsm_model_state_b16_s state;
struct pmsm_model_ext_b16_s ext;
b16_t per;
b16_t id_int;
b16_t iq_int;
};
* Public Functions Prototypes
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
b16_t fast_sin_b16(b16_t angle);
b16_t fast_sin2_b16(b16_t angle);
b16_t fast_cos_b16(b16_t angle);
b16_t fast_cos2_b16(b16_t angle);
b16_t fast_atan2_b16(b16_t y, b16_t x);
void f_saturate_b16(FAR b16_t *val, b16_t min, b16_t max);
b16_t vector2d_mag_b16(b16_t x, b16_t y);
void vector2d_saturate_b16(FAR b16_t *x, FAR b16_t *y, b16_t max);
void dq_saturate_b16(FAR dq_frame_b16_t *dq, b16_t max);
b16_t dq_mag_b16(FAR dq_frame_b16_t *dq);
void pid_controller_init_b16(FAR pid_controller_b16_t *pid,
b16_t KP, b16_t KI, b16_t KD);
void pi_controller_init_b16(FAR pid_controller_b16_t *pid,
b16_t KP, b16_t KI);
void pid_saturation_set_b16(FAR pid_controller_b16_t *pid, b16_t min,
b16_t max);
void pi_saturation_set_b16(FAR pid_controller_b16_t *pid, b16_t min,
b16_t max);
void pid_integral_reset_b16(FAR pid_controller_b16_t *pid);
void pi_integral_reset_b16(FAR pid_controller_b16_t *pid);
b16_t pi_controller_b16(FAR pid_controller_b16_t *pid, b16_t err);
b16_t pid_controller_b16(FAR pid_controller_b16_t *pid, b16_t err);
void pi_antiwindup_enable_b16(FAR pid_controller_b16_t *pid, b16_t KC,
bool enable);
void pi_ireset_enable_b16(FAR pid_controller_b16_t *pid, bool enable);
void clarke_transform_b16(FAR abc_frame_b16_t *abc, FAR ab_frame_b16_t *ab);
void inv_clarke_transform_b16(FAR ab_frame_b16_t *ab,
FAR abc_frame_b16_t *abc);
void park_transform_b16(FAR phase_angle_b16_t *angle, FAR ab_frame_b16_t *ab,
FAR dq_frame_b16_t *dq);
void inv_park_transform_b16(FAR phase_angle_b16_t *angle,
FAR dq_frame_b16_t *dq, FAR ab_frame_b16_t *ab);
void angle_norm_b16(FAR b16_t *angle, b16_t per, b16_t bottom, b16_t top);
void angle_norm_2pi_b16(FAR b16_t *angle, b16_t bottom, b16_t top);
void phase_angle_update_b16(FAR struct phase_angle_b16_s *angle, b16_t val);
void svm3_init_b16(FAR struct svm3_state_b16_s *s);
void svm3_b16(FAR struct svm3_state_b16_s *s, FAR ab_frame_b16_t *ab);
void svm3_current_correct_b16(FAR struct svm3_state_b16_s *s,
b16_t *c0, b16_t *c1, b16_t *c2);
void foc_init_b16(FAR struct foc_data_b16_s *foc,
FAR struct foc_initdata_b16_s *init);
void foc_vbase_update_b16(FAR struct foc_data_b16_s *foc, b16_t vbase);
void foc_angle_update_b16(FAR struct foc_data_b16_s *foc,
FAR phase_angle_b16_t *angle);
void foc_iabc_update_b16(FAR struct foc_data_b16_s *foc,
FAR abc_frame_b16_t *i_abc);
void foc_voltage_control_b16(FAR struct foc_data_b16_s *foc,
FAR dq_frame_b16_t *vdq_ref);
void foc_current_control_b16(FAR struct foc_data_b16_s *foc,
FAR dq_frame_b16_t *idq_ref,
FAR dq_frame_b16_t *vdq_comp,
FAR dq_frame_b16_t *v_dq_ref);
void foc_vabmod_get_b16(FAR struct foc_data_b16_s *foc,
FAR ab_frame_b16_t *v_ab_mod);
void foc_vdq_mag_max_get_b16(FAR struct foc_data_b16_s *foc, FAR b16_t *max);
void motor_sobserver_init_b16(FAR struct motor_sobserver_b16_s *observer,
FAR void *so, b16_t per);
void motor_aobserver_init_b16(FAR struct motor_aobserver_b16_s *observer,
FAR void *ao, b16_t per);
b16_t motor_sobserver_speed_get_b16(FAR struct motor_sobserver_b16_s *o);
b16_t motor_aobserver_angle_get_b16(FAR struct motor_aobserver_b16_s *o);
void motor_aobserver_smo_init_b16(FAR struct motor_aobserver_smo_b16_s *smo,
b16_t kslide, b16_t err_max);
void motor_aobserver_smo_b16(FAR struct motor_aobserver_b16_s *o,
FAR ab_frame_b16_t *i_ab,
FAR ab_frame_b16_t *v_ab,
FAR struct motor_phy_params_b16_s *phy,
b16_t dir, b16_t speed);
void motor_sobserver_div_init_b16(FAR struct motor_sobserver_div_b16_s *so,
uint8_t samples, b16_t filer, b16_t per);
void motor_sobserver_div_b16(FAR struct motor_sobserver_b16_s *o,
b16_t angle);
void motor_aobserver_nfo_init_b16(FAR struct motor_aobserver_nfo_b16_s *nfo);
void motor_aobserver_nfo_b16(FAR struct motor_aobserver_b16_s *o,
FAR ab_frame_b16_t *i_ab,
FAR ab_frame_b16_t *v_ab,
FAR struct motor_phy_params_b16_s *phy,
b16_t gain);
void motor_sobserver_pll_init_b16(FAR struct motor_sobserver_pll_b16_s *so,
b16_t pll_kp, b16_t pll_ki);
void motor_sobserver_pll_b16(FAR struct motor_sobserver_b16_s *o,
b16_t angle);
void motor_openloop_init_b16(FAR struct openloop_data_b16_s *op, b16_t per);
void motor_openloop_b16(FAR struct openloop_data_b16_s *op, b16_t speed,
b16_t dir);
b16_t motor_openloop_angle_get_b16(FAR struct openloop_data_b16_s *op);
void motor_angle_init_b16(FAR struct motor_angle_b16_s *angle, uint8_t p);
void motor_angle_e_update_b16(FAR struct motor_angle_b16_s *angle,
b16_t angle_new, b16_t dir);
void motor_angle_m_update_b16(FAR struct motor_angle_b16_s *angle,
b16_t angle_new, b16_t dir);
b16_t motor_angle_m_get_b16(FAR struct motor_angle_b16_s *angle);
b16_t motor_angle_e_get_b16(FAR struct motor_angle_b16_s *angle);
void motor_phy_params_init_b16(FAR struct motor_phy_params_b16_s *phy,
uint8_t poles, b16_t res, b16_t ind,
b16_t fluxlink);
void pmsm_phy_params_init_b16(FAR struct pmsm_phy_params_b16_s *phy,
uint8_t poles, b16_t res, b16_t ind,
b16_t iner, b16_t flux,
b16_t ind_d, b16_t ind_q);
int pmsm_model_initialize_b16(FAR struct pmsm_model_b16_s *model,
FAR struct pmsm_phy_params_b16_s *phy,
b16_t per);
int pmsm_model_elec_b16(FAR struct pmsm_model_b16_s *model,
FAR ab_frame_b16_t *vab);
int pmsm_model_mech_b16(FAR struct pmsm_model_b16_s *model, b16_t load);
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif