332 lines
9.6 KiB
C
Executable File
332 lines
9.6 KiB
C
Executable File
/****************************************************************************
|
|
|
|
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
|
|
|
|
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
|
|
be copied by any method or incorporated into another program without
|
|
the express written consent of Aerospace C.Power. This Information or any portion
|
|
thereof remains the property of Aerospace C.Power. The Information contained herein
|
|
is believed to be accurate and Aerospace C.Power assumes no responsibility or
|
|
liability for its use in any way and conveys no license or title under
|
|
any patent or copyright and makes no representation or warranty that this
|
|
Information is free from patent or copyright infringement.
|
|
|
|
****************************************************************************/
|
|
#ifndef ENERGE_METER_H
|
|
#define ENERGE_METER_H
|
|
|
|
#include "os_types.h"
|
|
#include "os_timer.h"
|
|
#include "iot_energe_meter.h"
|
|
#include "em_hw.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#define ENERGE_METER_HARMONIC_SUPPORT 1
|
|
#define ENERGE_METER_TD_FACTOR_SUPPORT 0
|
|
#define ENERGE_METER_DUMP_SAMPLE_DATA 0
|
|
#define ENERGE_METER_CAL_SUPPORT 1
|
|
#define ENERGE_MEMTER_DEBUG_EN 0
|
|
#define ENERGE_METER_TEST_DATA_USE 0
|
|
#define ENERGE_METER_PWR_AVG_CNT 8
|
|
|
|
#if ENERGE_MEMTER_BOARD_SUPPORT == IOT_PWR_METER_KL2_CUSTOM_BOARD
|
|
#define EM_COMPLEX_COMPENSATE_SUPPOERT (1)
|
|
#else
|
|
#define EM_COMPLEX_COMPENSATE_SUPPOERT (0)
|
|
#endif
|
|
|
|
/* max:600A@220V, unit:mW */
|
|
#define ENERGE_METER_POWER_SCALE_MAX 12000000000
|
|
#define ENERGE_METER_POWER_SCALE_U_MAX 1000
|
|
#define ENERGE_METER_POWER_SCALE_I_MAX 10000
|
|
#define ENERGE_METER_W2MW_X256 256000
|
|
#define ENERGE_METER_PULSE_WIDTH 80
|
|
|
|
#define PI 3.1415926
|
|
#define pi 804
|
|
#define H 21
|
|
|
|
/* power pulse static number */
|
|
#define ENERGE_METER_POWER_PULSE_C (900)
|
|
#define ENERGE_METER_POWER_PULSE_T (N/fs)
|
|
|
|
/* Descriptors for DMA-operation, RX/TX */
|
|
#define IOT_EM_DMA_DESC_NUM 16//8
|
|
#define IOT_EM_DMA_DESC_SIZE 2048
|
|
|
|
typedef struct energe_meter_nv_param_t
|
|
{
|
|
float U_scale_factor;
|
|
float I_scale_factor;
|
|
float P_scale_factor;
|
|
int U_dc_offset;
|
|
int I_dc_offset;
|
|
int P_dc_offset;
|
|
} energe_meter_nv_param;
|
|
|
|
typedef struct energe_meter_pulse_param_t
|
|
{
|
|
uint8_t gpio;
|
|
uint8_t start;
|
|
timer_id_t timer;
|
|
uint32_t pulse_dly_ms;
|
|
uint32_t pulse_num;
|
|
uint32_t pulse_width;
|
|
} energe_meter_pulse_param;
|
|
|
|
typedef enum {
|
|
SADC_Ua = 0,
|
|
SADC_Ub,
|
|
SADC_Uc,
|
|
SADC_Ia,
|
|
SADC_Ib,
|
|
SADC_Ic,
|
|
SADC_Ig,
|
|
SADC_Ud, /* charge pile */
|
|
SADC_Um, /* charge pile meter voltage */
|
|
SADC_Id, /* charge pile */
|
|
SADC_Ileak, /* charge pile */
|
|
} sadc_func_id_t;
|
|
|
|
typedef struct energe_meter_info_t
|
|
{
|
|
uint8_t init;
|
|
uint8_t lock;
|
|
uint8_t div_idx;
|
|
uint8_t dec_part_num;
|
|
uint8_t energe_pwr_ring_idx;
|
|
uint32_t energe_pulse_idx;
|
|
uint32_t energe_pulse_total;
|
|
int32_t T_k;/*temperature */
|
|
float Ta;
|
|
float Tb;
|
|
uint32_t sample_count;
|
|
uint32_t total_sample_count;
|
|
timer_id_t process_timer;
|
|
energe_meter_nv_param nv_param;
|
|
energe_meter_pulse_param pulse_param;
|
|
int64_t pulse_thd;
|
|
int64_t pulse_div_cnst;
|
|
int64_t energe_pwr_ring[ENERGE_METER_PWR_AVG_CNT];
|
|
int64_t energe_cur_pwr;
|
|
int64_t energe_pulse_pwr;
|
|
void* em_hw;
|
|
/* Pointer to the energy meter customer infomation buffer. */
|
|
void* em_custom;
|
|
iot_energe_meter_energe_cb energe_cb;
|
|
energe_meter_phase_data phase_data;
|
|
} energe_meter_info;
|
|
|
|
extern energe_meter_info *g_energe_meter_info;
|
|
extern const int32_t cos_tab[1024];
|
|
extern const int32_t sin_tab[1024];
|
|
|
|
/**
|
|
*@brief math_abs.
|
|
*
|
|
* Returns the absolute value of a number.
|
|
* The absolute value of a number is the number without its sign.
|
|
*
|
|
*@param x [int64_t number.]
|
|
*@exception [none.]
|
|
*@return [none.]
|
|
*/
|
|
int64_t math_abs(int64_t x);
|
|
|
|
/**
|
|
*@brief math_fast_sqrt.
|
|
*
|
|
* Fast returns the absolute value of a number.
|
|
* The absolute value of a number is the number without its sign.
|
|
*
|
|
*@param x [int64_t number.]
|
|
*@param y [magic number.]
|
|
*@exception [none.]
|
|
*@return [none.]
|
|
*/
|
|
int32_t math_fast_sqrt(int64_t x, int64_t y);
|
|
|
|
/**
|
|
*@brief math_sqrt.
|
|
*
|
|
* Returns a positive square root.
|
|
*
|
|
*@param x [int64_t number.]
|
|
*@exception [none.]
|
|
*@return [none.]
|
|
*/
|
|
int32_t math_sqrt(int64_t x);
|
|
|
|
/**
|
|
*@brief math_sqrt_newton_iterative.
|
|
*
|
|
* Returns a positive square root.
|
|
*
|
|
*@param x [float number.]
|
|
*@exception [none.]
|
|
*@return [none.]
|
|
*/
|
|
float math_sqrt_newton_iterative(float x);
|
|
|
|
/**
|
|
*@brief math_atan.
|
|
*
|
|
* Returns the arctangent, or inverse tangent, of a number.
|
|
* The arctangent is the angle whose tangent is number.
|
|
* The returned angle is given in radians in the range -pi/2 to pi/2.
|
|
*
|
|
*@param arg [double number.]
|
|
*@exception [none.]
|
|
*@return [none.]
|
|
*/
|
|
double math_atan(double x);
|
|
|
|
/**
|
|
*@brief math_atan2.
|
|
*
|
|
* Returns the arctangent, or inverse tangent, of the specified
|
|
* x- and y-coordinates. The arctangent is the angle from the x-axis
|
|
* to a line containing the origin (0, 0) and a point with coordinates
|
|
* (x_num, y_num). The angle is given in radians between -pi and pi,
|
|
* excluding -pi.
|
|
*
|
|
*@param arg1 [double number.]
|
|
*@param arg2 [double number.]
|
|
*@exception [none.]
|
|
*@return [none.]
|
|
*/
|
|
double math_atan2(double x, double y);
|
|
|
|
/**
|
|
* @brief iot_energe_meter_harmonic -
|
|
* Get frequency domain harmonic data from fft opration.
|
|
* @param data the array address of raw sample data.
|
|
* @param Am the array address of frequency domain harmonic data.
|
|
* @param Ang the array address of frequency domain angle.
|
|
* @param f the data frequency.
|
|
*/
|
|
#if EM_COMPLEX_COMPENSATE_SUPPOERT
|
|
void iot_energe_meter_harmonic(
|
|
int32_t data[], int32_t Am[], int32_t Ang[], int32_t f, uint8_t phase_index);
|
|
#else
|
|
void iot_energe_meter_harmonic(
|
|
int32_t data[], int32_t Am[], int32_t Ang[], int32_t f);
|
|
#endif
|
|
|
|
/**
|
|
* @brief iot_energe_meter_phase_harmonic_rms - calculate each phase's
|
|
* sample RMS value according to the amplitude of harmonic analysis.
|
|
* @param am pointer to the amplitude buffer.
|
|
* @param rms pointer to the rms value buffer.
|
|
*
|
|
*/
|
|
void iot_energe_meter_phase_harmonic_rms(int32_t *am, float *rms);
|
|
|
|
int32_t iot_energe_meter_angle(int32_t x1, int32_t x2, int32_t x3,int32_t x4);
|
|
|
|
void iot_energe_meter_interpolate (int32_t w[],int32_t ang[],int32_t Am[],int32_t Ang[]);
|
|
|
|
void iot_energe_meter_power(int32_t *am_u,
|
|
int32_t *am_i, int32_t *ph_u, int32_t *ph_i, int64_t *p_fd, int64_t *q_fd);
|
|
|
|
void iot_energe_meter_vol_curr(int32_t *am_u, int32_t *am_i, uint32_t *u_fd, uint32_t *i_fd);
|
|
|
|
int32_t iot_energe_meter_reactive_power(
|
|
uint32_t sample_count, int32_t *U_data, int32_t *I_data);
|
|
|
|
/**
|
|
* @brief iot_energe_meter_frequency_common - calculate signal frequency.
|
|
* @param sample_count counter of sample data.
|
|
* @param U_data pointer to the sample data value buffer.
|
|
* @param sample_freq sample frequency.
|
|
* @return freq signal frequency.
|
|
*
|
|
*/
|
|
uint32_t iot_energe_meter_frequency(uint32_t sample_count,
|
|
int32_t *U_data, uint32_t sample_freq);
|
|
|
|
/**
|
|
*@brief em_timer_data_output.
|
|
*
|
|
* energe meter debug output depend on timer.
|
|
*
|
|
*@param g_em_pt [meter global pointer.]
|
|
*@exception [none.]
|
|
*@return [none.]
|
|
*/
|
|
void em_timer_data_output(energe_meter_info *g_em_pt);
|
|
|
|
/**
|
|
*@brief em_load_calibration.
|
|
*
|
|
* energe meter load calibration data.
|
|
*
|
|
*@param para_pt [meter global pointer.]
|
|
*@exception [none.]
|
|
*@return [none.]
|
|
*/
|
|
void em_load_calibration(void *para_pt);
|
|
|
|
/**
|
|
*@brief em_hw_get_active_pwr.
|
|
*
|
|
* get active power depend on phase number.
|
|
*
|
|
*@param para_pt [meter global pointer.]
|
|
*@param phase_num [phase number.]
|
|
*@exception [none.]
|
|
*@return [none.]
|
|
*/
|
|
float em_hw_get_active_pwr(energe_meter_info *g_em_pt, sadc_func_id_t phase_num);
|
|
|
|
/**
|
|
*@brief em_hw_get_reactive_pwr.
|
|
*
|
|
* get reactive power depend on phase number.
|
|
*
|
|
*@param para_pt [meter global pointer.]
|
|
*@param phase_num [phase number.]
|
|
*@exception [none.]
|
|
*@return [none.]
|
|
*/
|
|
float em_hw_get_reactive_pwr(energe_meter_info *g_em_pt, sadc_func_id_t phase_num);
|
|
|
|
/**
|
|
*@brief em_hw_get_freq.
|
|
*
|
|
* get data frequency depend on phase number.
|
|
*
|
|
*@param para_pt [meter global pointer.]
|
|
*@param phase_num [phase number.]
|
|
*@exception [none.]
|
|
*@return [none.]
|
|
*/
|
|
uint32_t em_hw_get_freq(energe_meter_info *g_em_pt, sadc_func_id_t phase_num);
|
|
|
|
/**
|
|
*@brief em_hw_fft_harmonic.
|
|
*
|
|
* get frequency domain harmonic data from fft opration.
|
|
*
|
|
*@param data [raw sample data.]
|
|
*@param hmn [frequency domain harmonic data.]
|
|
*@param ang [frequency domain angle.]
|
|
*@param f [data frequency.]
|
|
*@exception [none.]
|
|
*@return [none.]
|
|
*/
|
|
#if EM_COMPLEX_COMPENSATE_SUPPOERT
|
|
void em_hw_fft_harmonic(int32_t *data, int32_t *hmn,int32_t *ang,int32_t f, uint8_t phase_index);
|
|
#else
|
|
void em_hw_fft_harmonic(int32_t *data, int32_t *hmn,int32_t *ang,int32_t f);
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /*ENERGE_METER_H*/
|