You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1818 lines
43 KiB
C
1818 lines
43 KiB
C
/*****************************************************************************
|
|
* file lib/process/pd_dau.c
|
|
* author YuLiang
|
|
* version 1.0.0
|
|
* date 03-Feb-2023
|
|
* brief This file provides all the dau related operation functions.
|
|
******************************************************************************
|
|
* Attention
|
|
*
|
|
* <h2><center>© COPYRIGHT(c) 2021 LandPower</center></h2>
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without modification,
|
|
* are permitted provided that the following conditions are met:
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
* 3. Neither the name of LandPower nor the names of its contributors may be used to
|
|
* endorse or promote products derived from this software without specific
|
|
* prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
******************************************************************************/
|
|
|
|
/* Includes ------------------------------------------------------------------*/
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#ifdef CFG_DEV_TYPE_LAND_PD
|
|
/* 标准C库头文件. */
|
|
#include <sys/mman.h>
|
|
#include <sys/types.h>
|
|
#include <sys/time.h>
|
|
#include <sys/ipc.h>
|
|
#include <sys/msg.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/socket.h>
|
|
#include <fcntl.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
#include <pthread.h>
|
|
|
|
#include "vty.h"
|
|
#include "cmd.h"
|
|
#include "fifo.h"
|
|
#include "mtimer.h"
|
|
#include "hwgpio.h"
|
|
|
|
#include "main.h"
|
|
#include "pd_main.h"
|
|
#include "pd_csg.h"
|
|
#include "pd_net.h"
|
|
#include "pd_dau.h"
|
|
#include "pd_dbg.h"
|
|
|
|
/* Private typedef -----------------------------------------------------------*/
|
|
typedef struct
|
|
{
|
|
uint32_t ASPR[DAU_ADJ_POINT_SUM]; // 校准分段点
|
|
uint32_t AFR[DAU_ADJ_POINT_SUM]; // 校准系数
|
|
} dau_adj_port_t;
|
|
|
|
typedef struct
|
|
{
|
|
dau_adj_port_t port[PD_DAU_PORT_SUM];
|
|
} dau_adj_t;
|
|
|
|
/* Private define ------------------------------------------------------------*/
|
|
#define DAU_ADJ_FILE "adj.cfg"
|
|
#define DAU_ADJ_FILE_BAK "./bak/adj.cfg"
|
|
#define DAU_CODE 0x0701
|
|
|
|
/* Private macro -------------------------------------------------------------*/
|
|
|
|
/* Private variables ---------------------------------------------------------*/
|
|
dau_ctrl_t dau_ctrl;
|
|
dau_t *dau[PD_DAU_SUM];
|
|
|
|
/* DAU 端口类型分类 */
|
|
static const char *dau_port_type_str[PD_PORT_TYPE_COUNT] =
|
|
{
|
|
"",
|
|
"uhf",
|
|
"ae",
|
|
"tev",
|
|
"hf"
|
|
};
|
|
|
|
extern dau_port_func_t uhf_func;
|
|
extern dau_port_func_t hf_func;
|
|
|
|
/* Private function prototypes -----------------------------------------------*/
|
|
extern int32_t _dau_add(uint8_t unit, uint8_t port_num);
|
|
extern void _dau_del(uint8_t unit);
|
|
|
|
/* Internal functions --------------------------------------------------------*/
|
|
/* 添加 DAU 模块命令 */
|
|
CMD(dau_add,
|
|
dau_add_cmd,
|
|
"dau <1-1> port-num <1-8>",
|
|
"DAU\n"
|
|
"Unit id\n"
|
|
"Port\n"
|
|
"Port number\n")
|
|
{
|
|
uint8_t unit = 0;
|
|
uint8_t port_num = 0;
|
|
|
|
unit = strtol(argv[0], NULL, 10) - 1;
|
|
port_num = strtol(argv[1], NULL, 10);
|
|
|
|
_dau_add(unit, port_num);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
/* 删除 DAU 模块命令 */
|
|
CMD(no_dau_add,
|
|
no_dau_add_cmd,
|
|
"no dau <1-1>",
|
|
"no\n"
|
|
"DAU\n"
|
|
"Unit id\n"
|
|
"Port\n"
|
|
"Port number\n")
|
|
{
|
|
uint8_t unit = 0;
|
|
|
|
unit = strtol(argv[0], NULL, 10) - 1;
|
|
|
|
_dau_del(unit);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
/* 配置端口模式. */
|
|
CMD(dau_port_type,
|
|
dau_port_type_cmd,
|
|
"port-type (uhf|ae|tev|hf)",
|
|
"DAU port type\n"
|
|
"UHF\n"
|
|
"AE\n"
|
|
"TEV\n"
|
|
"HF\n")
|
|
{
|
|
dau_t *dau_node = NULL;
|
|
uint8_t unit = 0;
|
|
uint8_t port = 0;
|
|
uint8_t port_type = 0;
|
|
uint32_t temp = 0;
|
|
|
|
/* 取出端口号. */
|
|
if (dau_vport_to_port(pd_port_node.param_num, &unit, &port) != E_NONE)
|
|
{
|
|
return CMD_ERR_NO_MATCH;
|
|
}
|
|
|
|
for(port_type = PD_PORT_TYPE_UHF; port_type < PD_PORT_TYPE_COUNT; port_type++)
|
|
{
|
|
if (strncmp(argv[0], dau_port_type_str[port_type], strlen(dau_port_type_str[port_type])))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
dau_node = dau[unit];
|
|
temp = (port_type << DAU_CR_PT_Pos);
|
|
if (is_system_init)
|
|
{
|
|
MODIFY_REG(dau_node->reg->reg_port[port].CR, DAU_CR_PT_Msk, temp);
|
|
}
|
|
|
|
pd_config.config_port[unit][port].port_type = port_type;
|
|
if (PD_PORT_TYPE_UHF == port_type)
|
|
{
|
|
dau_node->port_func[port] = &uhf_func;
|
|
}
|
|
else if (PD_PORT_TYPE_AE == port_type)
|
|
{
|
|
dau_node->port_func[port] = &uhf_func;
|
|
}
|
|
else if (PD_PORT_TYPE_HF == port_type)
|
|
{
|
|
dau_node->port_func[port] = &hf_func;
|
|
}
|
|
else
|
|
{
|
|
dau_node->port_func[port] = &uhf_func;
|
|
}
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
/* 通道滤波类型. */
|
|
CMD(dau_filter_type,
|
|
dau_filter_type_cmd,
|
|
"filtrate-type (none|ff|fr|lf|hf)",
|
|
"Port filtrate type\n"
|
|
"None\n"
|
|
"Full frequency \n"
|
|
"Full frequency resistor\n"
|
|
"Low frequency\n"
|
|
"High frequency\n")
|
|
{
|
|
dau_t *dau_node = NULL;
|
|
uint8_t unit = 0;
|
|
uint8_t port = 0;
|
|
uint8_t filter = 0;
|
|
uint8_t filter_csg = 0;
|
|
uint32_t temp = 0;
|
|
|
|
/* 取出端口号. */
|
|
if (dau_vport_to_port(pd_port_node.param_num, &unit, &port) != E_NONE)
|
|
{
|
|
return CMD_ERR_NO_MATCH;
|
|
}
|
|
|
|
if (0 == strncmp(argv[0], "hf", 2))
|
|
{
|
|
filter = PD_FILTER_TYPE_HF;
|
|
filter_csg = CSG_FILTER_TYPE_HF;
|
|
}
|
|
else if (0 == strncmp(argv[0], "lf", 2))
|
|
{
|
|
filter = PD_FILTER_TYPE_LF;
|
|
filter_csg = CSG_FILTER_TYPE_LF;
|
|
}
|
|
else if (0 == strncmp(argv[0], "fr", 2))
|
|
{
|
|
filter = PD_FILTER_TYPE_FR;
|
|
filter_csg = CSG_FILTER_TYPE_FR;
|
|
}
|
|
else if (0 == strncmp(argv[0], "ff", 2))
|
|
{
|
|
filter = PD_FILTER_TYPE_FF;
|
|
filter_csg = CSG_FILTER_TYPE_FF;
|
|
}
|
|
else
|
|
{
|
|
filter = 0;
|
|
}
|
|
|
|
dau_node = dau[unit];
|
|
temp = (filter << DAU_CR_FT_Pos);
|
|
if (is_system_init)
|
|
{
|
|
MODIFY_REG(dau_node->reg->reg_port[port].CR, DAU_CR_FT_Msk, temp);
|
|
}
|
|
pd_config.config_port[unit][port].filter = filter_csg;
|
|
pd_config.config_real[unit][port].filter_cfg = filter_csg;
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
/* 显示 DAU 状态. */
|
|
CMD(show_dau_status_all,
|
|
show_dau_status_all_cmd,
|
|
"show dau",
|
|
"Show\n"
|
|
"DAU\n")
|
|
{
|
|
uint8_t unit = 0;
|
|
|
|
for(unit = 0; unit < PD_DAU_SUM; unit++)
|
|
{
|
|
dau_show(unit);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
/* 显示 DAU 校准系数. */
|
|
CMD(show_dau_vaule,
|
|
show_dau_vaule_cmd,
|
|
"show dau vaule",
|
|
"Show\n"
|
|
"DAU\n"
|
|
"Vaule\n")
|
|
{
|
|
uint8_t unit = 0;
|
|
|
|
for(unit = 0; unit < PD_DAU_SUM; unit++)
|
|
{
|
|
dau_show_value(unit);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
/* 显示 DAU 校准系数. */
|
|
CMD(show_dau_adj_all,
|
|
show_dau_adj_all_cmd,
|
|
"show dau adj",
|
|
"Show\n"
|
|
"DAU\n"
|
|
"ADJ\n")
|
|
{
|
|
uint8_t unit = 0;
|
|
|
|
for(unit = 0; unit < PD_DAU_SUM; unit++)
|
|
{
|
|
dau_show_adj(unit);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
/* 显示 DAU 全局寄存器. */
|
|
CMD(show_dau_reg_all,
|
|
show_dau_reg_all_cmd,
|
|
"show dau reg",
|
|
"Show\n"
|
|
"DAU\n"
|
|
"Reg\n")
|
|
{
|
|
uint8_t unit = 0;
|
|
|
|
for(unit = 0; unit < PD_DAU_SUM; unit++)
|
|
{
|
|
dau_show_reg(unit);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
/* 显示 DAU 全局寄存器. */
|
|
CMD(show_dau_reg_port,
|
|
show_dau_reg_port_cmd,
|
|
"show dau port <1-8>",
|
|
"Show\n"
|
|
"DAU\n"
|
|
"Port Reg\n"
|
|
"Port number")
|
|
{
|
|
uint8_t vport = 0;
|
|
uint8_t unit = 0;
|
|
uint8_t port = 0;
|
|
|
|
vport = strtol(argv[0], NULL, 10);
|
|
|
|
/* 取出端口号. */
|
|
if (dau_vport_to_port(vport, &unit, &port) != E_NONE)
|
|
{
|
|
return CMD_ERR_NO_MATCH;
|
|
}
|
|
|
|
dau_show_reg_port(unit, port);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
/* DAU 测试函数. */
|
|
void *_dau_test_handle(void *arg)
|
|
{
|
|
dau_t *dau_node = NULL;
|
|
uint32_t i, j, k;
|
|
uint8_t bank = 0;
|
|
uint8_t temp = 0;
|
|
|
|
while(!dau_is_valid(dau[0]))
|
|
{
|
|
sleep(1);
|
|
}
|
|
|
|
dau_node = dau[0];
|
|
for(i = 0; i < PD_DAU_PORT_SUM; i++)
|
|
{
|
|
for(j = 0; j < PD_PRPS_NUM_MAX; j++)
|
|
{
|
|
if ((j & 0xff) == temp)
|
|
{
|
|
dau_node->PRPS->bank[bank].time[j][i] = j << 5;
|
|
dau_node->PRPS->bank[bank].data[j][i] = -200;
|
|
}
|
|
else
|
|
{
|
|
dau_node->PRPS->bank[bank].time[j][i] = 0;
|
|
dau_node->PRPS->bank[bank].data[j][i] = -750;
|
|
}
|
|
}
|
|
}
|
|
|
|
for(i = 0; i < PD_DAU_PORT_SUM; i++)
|
|
{
|
|
for(j = 0; j < PD_PHASE_NUM; j++)
|
|
{
|
|
for(k = 0; k < PD_TREND_PHASE_POINT_CNT; k++)
|
|
{
|
|
dau_node->original->point[j][i].data[k] = (k * 3) - 800;
|
|
}
|
|
}
|
|
}
|
|
|
|
dau_node->reg->reg_global.GPFPCR = 50;
|
|
dau_node->reg->reg_global.GPFPCCR = 2000000;
|
|
|
|
while(1)
|
|
{
|
|
/* 轮询间隔 */
|
|
sleep(1);
|
|
bank = !bank;
|
|
temp += 8;
|
|
|
|
for(i = 0; i < PD_DAU_PORT_SUM; i++)
|
|
{
|
|
for(j = 0; j < PD_PRPS_NUM_MAX; j++)
|
|
{
|
|
if ((j & 0xff) == temp)
|
|
{
|
|
dau_node->PRPS->bank[bank].time[j][i] = j << 5;
|
|
dau_node->PRPS->bank[bank].data[j][i] = -200;
|
|
}
|
|
else
|
|
{
|
|
dau_node->PRPS->bank[bank].time[j][i] = 0;
|
|
dau_node->PRPS->bank[bank].data[j][i] = -750;
|
|
}
|
|
}
|
|
}
|
|
|
|
dau_node->reg->reg_global.GSDPCR++;
|
|
dau_node->reg->reg_global.GPFPCR = 50;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/* DAU 模块添加处理函数 */
|
|
int32_t _dau_add(uint8_t unit, uint8_t port_num)
|
|
{
|
|
dau_t *dau_node = dau[unit];
|
|
|
|
DBG(DBG_M_PD_DAU, "Entry: unit %d port_num %d\r\n", unit, port_num);
|
|
|
|
/* 申请配置节点空间. */
|
|
if (!dau_node)
|
|
{
|
|
dau_node = XMALLOC(MTYPE_DAU, sizeof(dau_t));
|
|
if (!dau_node)
|
|
{
|
|
dau_node = NULL;
|
|
return E_MEM;
|
|
}
|
|
|
|
/* 初始化 DAU 结构体. */
|
|
dau_node->is_del = FALSE;
|
|
dau_node->reg = 0;
|
|
dau_node->PRPS = 0;
|
|
dau_node->original = 0;
|
|
dau_node->is_connect = FALSE;
|
|
|
|
dau[unit] = dau_node;
|
|
}
|
|
|
|
dau_node->unit = unit;
|
|
dau_node->port_num = port_num;
|
|
|
|
DBG(DBG_M_PD_DAU, "Leave\r\n");
|
|
return E_NONE;
|
|
}
|
|
|
|
/* DAU 模块删除处理函数 */
|
|
void _dau_del(uint8_t unit)
|
|
{
|
|
dau_t *dau_node = dau[unit];
|
|
|
|
if (!dau_node)
|
|
{
|
|
return;
|
|
}
|
|
|
|
dau_node->is_del = TRUE;
|
|
dau_node->is_valid = FALSE;
|
|
}
|
|
|
|
/* 发送数据到后台通讯进程. */
|
|
int32_t _dau_msg_send_csg(uint32_t type, void *data)
|
|
{
|
|
int32_t fifo_id;
|
|
pd_csg_msg_t up_msg;
|
|
|
|
/* 封装消息. */
|
|
up_msg.type = type;
|
|
up_msg.data = data;
|
|
|
|
if (PD_PROTOCOL_LAND == pd_config.config.protocol_type)
|
|
{
|
|
if (PD_SEND_TYPE_PRPS == type)
|
|
{
|
|
fifo_id = csg.fifo_prps_id;
|
|
}
|
|
else if (PD_SEND_TYPE_TREND == type)
|
|
{
|
|
fifo_id = csg.fifo_trend_id;
|
|
}
|
|
else if (PD_SEND_TYPE_EVENT == type)
|
|
{
|
|
fifo_id = csg.fifo_event_id;
|
|
}
|
|
}
|
|
else if (PD_PROTOCOL_CSG == pd_config.config.protocol_type)
|
|
{
|
|
if (PD_SEND_TYPE_PRPS == type)
|
|
{
|
|
fifo_id = net.fifo_prps_id;
|
|
}
|
|
else if (PD_SEND_TYPE_TREND == type)
|
|
{
|
|
fifo_id = net.fifo_trend_id;
|
|
}
|
|
else if (PD_SEND_TYPE_EVENT == type)
|
|
{
|
|
fifo_id = net.fifo_event_id;
|
|
}
|
|
}
|
|
|
|
if (fifo_id <= 0)
|
|
return E_NONE;
|
|
|
|
/* 发送消息 */
|
|
if (fifo_write(fifo_id, (void*)(&up_msg), sizeof(pd_csg_msg_t)) != sizeof(pd_csg_msg_t))
|
|
{
|
|
DBG(DBG_M_PD_DAU_ERR, "DAU write ERROR! type=%d\r\n", type);
|
|
return E_ERROR;
|
|
}
|
|
return E_NONE;
|
|
}
|
|
|
|
/* 实时数据降噪处理. */
|
|
void _dau_sec_data_real(void)
|
|
{
|
|
struct timeval now;
|
|
dau_t *dau_node = NULL;
|
|
uint8_t unit = 0;
|
|
uint8_t port = 0;
|
|
|
|
/* 申请 PRPS 数据空间. */
|
|
pd_data.real = XMALLOC_Q(MTYPE_CSG, sizeof(pd_prps_point_t));
|
|
if (!pd_data.real)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* 自动 / 手动降噪. */
|
|
for(unit = 0; unit < PD_DAU_SUM; unit++)
|
|
{
|
|
dau_node = dau[unit];
|
|
if (!dau_is_valid(dau_node))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
for(port = 0; port < dau_node->port_num; port++)
|
|
{
|
|
if (!dau_node->port_func[port]->denoise_real)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
dau_node->port_func[port]->denoise_real(unit, port);
|
|
}
|
|
}
|
|
|
|
/* 关联降噪. */
|
|
for(unit = 0; unit < PD_DAU_SUM; unit++)
|
|
{
|
|
dau_node = dau[unit];
|
|
if (!dau_is_valid(dau_node))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
for(port = 0; port < dau_node->port_num; port++)
|
|
{
|
|
if (!dau_node->port_func[port]->denoise_real_r)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
dau_node->port_func[port]->denoise_real_r(unit, port);
|
|
}
|
|
}
|
|
|
|
/* 降噪数据统计 (PRPS 显示). */
|
|
for(unit = 0; unit < PD_DAU_SUM; unit++)
|
|
{
|
|
dau_node = dau[unit];
|
|
if (!dau_is_valid(dau_node))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
for(port = 0; port < dau_node->port_num; port++)
|
|
{
|
|
if (!dau_node->port_func[port]->denoise_real_state)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
dau_node->port_func[port]->denoise_real_state(unit, port);
|
|
}
|
|
}
|
|
|
|
pd_data.real->index = dau_ctrl.real_idx++;
|
|
gettimeofday(&now, NULL);
|
|
pd_data.real->utc = now.tv_sec;
|
|
pd_data.real->ms = now.tv_usec / 1000;
|
|
}
|
|
|
|
/* PRPS 实时图谱数据发送 */
|
|
void _dau_sec_data_real_send(void)
|
|
{
|
|
if (_dau_msg_send_csg(PD_SEND_TYPE_PRPS, pd_data.real) != E_NONE)
|
|
{
|
|
XFREE(MTYPE_CSG, pd_data.real);
|
|
}
|
|
}
|
|
|
|
/* PRPS 数据事件处理 */
|
|
void _dau_sec_data_event(void)
|
|
{
|
|
static uint8_t data_cnt = 0; // 保证丢包时能正确统计事件.
|
|
dau_t *dau_node = NULL;
|
|
uint8_t event_cnt = 0;
|
|
uint8_t is_send = FALSE;
|
|
uint8_t unit = 0;
|
|
uint8_t port = 0;
|
|
|
|
event_cnt = dau[0]->reg->reg_global.GSDPCR % DAU_EVENT_SUM;
|
|
|
|
/* 申请数据空间. */
|
|
if (NULL == pd_data.event)
|
|
{
|
|
pd_data.event = XMALLOC_Q(MTYPE_CSG, sizeof(pd_event_t));
|
|
if (!pd_data.event)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* 初始化 */
|
|
for(unit = 0; unit < PD_DAU_SUM; unit++)
|
|
{
|
|
dau_node = dau[unit];
|
|
if (!dau_is_valid(dau_node))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
for(port = 0; port < dau_node->port_num; port++)
|
|
{
|
|
if (!dau_node->port_func[port]->event_init)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
dau_node->port_func[port]->event_init(unit, port);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* 事件处理 */
|
|
for(unit = 0; unit < PD_DAU_SUM; unit++)
|
|
{
|
|
dau_node = dau[unit];
|
|
if (!dau_is_valid(dau_node))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
for(port = 0; port < dau_node->port_num; port++)
|
|
{
|
|
if (!dau_node->port_func[port]->event)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
dau_node->port_func[port]->event(unit, port, event_cnt);
|
|
|
|
if (pd_data.event->port[unit][port].type != PD_EVENT_TYPE_NONE)
|
|
{
|
|
dau_ctrl.event_index[unit][port]++;
|
|
is_send = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* 上送后台 */
|
|
data_cnt++;
|
|
if (data_cnt >= DAU_EVENT_SUM
|
|
|| event_cnt == (DAU_EVENT_SUM - 1))
|
|
{
|
|
if (is_send)
|
|
{
|
|
if (_dau_msg_send_csg(PD_SEND_TYPE_EVENT, pd_data.event) != E_NONE)
|
|
{
|
|
XFREE(MTYPE_CSG, pd_data.event);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* 没有事件产生要释放内存 */
|
|
XFREE(MTYPE_CSG, pd_data.event);
|
|
}
|
|
|
|
/* 发送给后台后, 地址清零. */
|
|
pd_data.event = NULL;
|
|
data_cnt = 0;
|
|
}
|
|
}
|
|
|
|
/* 趋势数据处理. */
|
|
void _dau_sec_data_trend(void)
|
|
{
|
|
dau_t *dau_node = NULL;
|
|
uint16_t trend_sec = 0;
|
|
uint8_t unit = 0;
|
|
uint8_t port = 0;
|
|
|
|
/* 趋势计算计数 */
|
|
trend_sec = dau[0]->reg->reg_global.GSDPCR % pd_config.config.trend_period;
|
|
|
|
/* 申请数据空间. */
|
|
if (NULL == pd_data.trend_prpd)
|
|
{
|
|
pd_data.trend_prpd = XMALLOC(MTYPE_CSG, sizeof(pd_trend_prpd_t));
|
|
if (!pd_data.trend_prpd)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* 初始化 */
|
|
for(unit = 0; unit < PD_DAU_SUM; unit++)
|
|
{
|
|
dau_node = dau[unit];
|
|
if (!dau_is_valid(dau_node))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
for(port = 0; port < dau_node->port_num; port++)
|
|
{
|
|
if (!dau_node->port_func[port]->trend_init)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
dau_node->port_func[port]->trend_init(unit, port);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* 数据处理 */
|
|
for(unit = 0; unit < PD_DAU_SUM; unit++)
|
|
{
|
|
dau_node = dau[unit];
|
|
if (!dau_is_valid(dau_node))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
for(port = 0; port < dau_node->port_num; port++)
|
|
{
|
|
if (!dau_node->port_func[port]->trend)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
dau_node->port_func[port]->trend(unit, port, trend_sec);
|
|
}
|
|
}
|
|
|
|
/* 通知趋势线程处理后续数据 */
|
|
if (trend_sec == (pd_config.config.trend_period - 1))
|
|
{
|
|
pd_data.trend_col.utc = pd_data.real->utc;
|
|
pd_data.trend_col.index = dau_ctrl.trend_idx++;
|
|
memcpy(&pd_data.trend.col, &pd_data.trend_col, sizeof(pd_trend_col_t));
|
|
pd_data.trend.prpd = pd_data.trend_prpd;
|
|
pd_data.trend_prpd = NULL;
|
|
pthread_mutex_unlock(&dau_ctrl.mutex);
|
|
}
|
|
}
|
|
|
|
/* 1s prps 数据处理. */
|
|
void _dau_sec_data_process(void)
|
|
{
|
|
static uint8_t data_cnt = 0;
|
|
|
|
/* 上电非稳定期间的数据丢弃 */
|
|
if (data_cnt < 3)
|
|
{
|
|
data_cnt++;
|
|
return;
|
|
}
|
|
|
|
/* 实时数据降噪处理. */
|
|
_dau_sec_data_real();
|
|
|
|
/* 事件计算 */
|
|
_dau_sec_data_event();
|
|
|
|
/* 趋势数据处理 */
|
|
_dau_sec_data_trend();
|
|
|
|
/* 实时数据发送处理. */
|
|
_dau_sec_data_real_send();
|
|
}
|
|
|
|
/* DAU 数据处理函数. */
|
|
void *_dau_sec_data_handle(void *arg)
|
|
{
|
|
uint32_t *time = NULL;
|
|
int16_t *data = NULL;
|
|
uint8_t bank = 0;
|
|
uint32_t i = 0;
|
|
uint32_t j = 0;
|
|
uint32_t period = 0;
|
|
uint32_t prps_cnt = 0;
|
|
|
|
/* 等待初始化完成 */
|
|
while(!is_system_init)
|
|
{
|
|
sleep(1);
|
|
}
|
|
|
|
while(1)
|
|
{
|
|
/* 轮询间隔 */
|
|
usleep(100000);
|
|
|
|
if (!dau_is_valid(dau[0]))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
/* 判断工频周期是否更新, 更新后才处理数据 */
|
|
if (period == dau[0]->reg->reg_global.GSDPCR)
|
|
{
|
|
continue;
|
|
}
|
|
period = dau[0]->reg->reg_global.GSDPCR;
|
|
|
|
//struct timeval tv;
|
|
//gettimeofday(&tv, NULL); // 获取当前时间
|
|
//printf("Seconds: %ld, Microseconds: %ld\n", tv.tv_sec, tv.tv_usec);
|
|
|
|
/* 确定 bank */
|
|
bank = (period & 0x1) ? 1 : 0;
|
|
//printf("#D0 %lld %d %d %d\r\n", dau[0]->reg->reg_global.GPFPCR, dau[0]->reg->reg_global.reserved0, period, bank);
|
|
|
|
/* 复制数据 */
|
|
prps_cnt = dau[0]->reg->reg_global.GPFPCR << 8;
|
|
time = (uint32_t*)(dau[0]->PRPS->bank[bank].time);
|
|
data = (int16_t*)(dau[0]->PRPS->bank[bank].data);
|
|
for(i = 0; i < dau[0]->port_num; i++)
|
|
{
|
|
dau[0]->port_state[i].prps_fre_cnt = dau[0]->reg->reg_global.GPFPCR;
|
|
for(j = 0; j < prps_cnt; j++)
|
|
{
|
|
dau[0]->port_state[i].prps[j].time = time[i + (j << 3)];
|
|
dau[0]->port_state[i].prps[j].data = data[i + (j << 3)];
|
|
#if 0
|
|
if (((j & 0xff) == 128) && 0 == i)
|
|
dau[0]->port_state[i].prps[j] = 1000;
|
|
else if(((j & 0x1ff) == 64) && 0 == i)
|
|
dau[0]->port_state[i].prps[j] = 3000;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/* 数据处理 */
|
|
_dau_sec_data_process();
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/* 趋势原始数据排序 */
|
|
void _dau_trend_original_sort(uint8_t unit)
|
|
{
|
|
dau_t *dau_node = dau[unit];
|
|
int16_t *point = NULL;
|
|
int16_t *point_bak = NULL;
|
|
uint8_t port = 0;
|
|
uint32_t i = 0;
|
|
|
|
for(port = 0; port < dau_node->port_num; port++)
|
|
{
|
|
for(i = 0; i < PD_PHASE_NUM; i++)
|
|
{
|
|
point = dau_node->original->point[i][port].data;
|
|
point_bak = pd_data.trend.original.port[unit][port].data[i];
|
|
memcpy(point_bak, point, PD_TREND_PHASE_POINT_CNT * sizeof(int16_t));
|
|
}
|
|
}
|
|
}
|
|
|
|
/* 趋势数据处理函数. */
|
|
void *_dau_trend_handle(void *arg)
|
|
{
|
|
dau_t *dau_node = NULL;
|
|
uint8_t unit = 0;
|
|
|
|
/* 等待初始化完成 */
|
|
while (!is_system_init)
|
|
{
|
|
sleep(1);
|
|
}
|
|
|
|
while (1)
|
|
{
|
|
/* 等待趋势数据 */
|
|
pthread_mutex_lock(&dau_ctrl.mutex);
|
|
|
|
if (PD_DEV_TYPE_UHF == device_info.type_s)
|
|
{
|
|
/* 原始数据处理 */
|
|
for(unit = 0; unit < PD_DAU_SUM; unit++)
|
|
{
|
|
dau_node = dau[unit];
|
|
if (!dau_is_valid(dau_node))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
_dau_trend_original_sort(unit);
|
|
}
|
|
}
|
|
|
|
//buf_print_16(pd_data.trend.prpd->port[0][0].data, 65536);
|
|
|
|
if (_dau_msg_send_csg(PD_SEND_TYPE_TREND, pd_data.trend.prpd) != E_NONE)
|
|
{
|
|
XFREE(MTYPE_CSG, pd_data.trend.prpd);
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/* 读通道校准系数. */
|
|
int32_t _dau_param_adj_get(uint8_t unit)
|
|
{
|
|
dau_adj_t adj;
|
|
int fd = 0;
|
|
ssize_t len = 0;
|
|
uint8_t port = 0;
|
|
|
|
fd = open(DAU_ADJ_FILE, O_RDWR | O_CREAT, 0777);
|
|
if (fd < 0 )
|
|
{
|
|
DBG(DBG_M_PD_DAU_ERR, "Open %s ERROR!\r\n", DAU_ADJ_FILE);
|
|
return E_SYS_CALL;
|
|
}
|
|
|
|
len = read(fd, &adj, sizeof(dau_adj_t));
|
|
if (len <= 0)
|
|
{
|
|
DBG(DBG_M_PD_DAU_ERR, "Read %s len %d!\r\n", DAU_ADJ_FILE, len);
|
|
memset(&adj, 0, sizeof(dau_adj_t));
|
|
}
|
|
|
|
for(port = 0; port < PD_DAU_PORT_SUM; port++)
|
|
{
|
|
/* 4G 单元控制特殊处理, 后期修改掉 */
|
|
dau[unit]->reg->reg_port[port].ASPR[0] = adj.port[port].ASPR[0];
|
|
dau[unit]->reg->reg_port[port].AFR[0] = adj.port[port].AFR[0];
|
|
//memcpy(dau[unit]->reg->reg_port[port].ASPR, &(adj.port[port]), sizeof(dau_adj_port_t));
|
|
}
|
|
|
|
close(fd);
|
|
return E_NONE;
|
|
}
|
|
|
|
/* dau 寄存器物理地址映射 */
|
|
int32_t _dau_reg_map(uint8_t unit)
|
|
{
|
|
if (dau_ctrl.fd_mmu != 0)
|
|
{
|
|
return E_NONE;
|
|
}
|
|
|
|
dau_ctrl.fd_mmu = open("/dev/mem", O_RDWR);
|
|
|
|
/* 映射寄存器 */
|
|
dau[unit]->reg = (dau_reg_t*)mmap(0, DAU_MEM_REG_LEN, PROT_READ | PROT_WRITE, MAP_SHARED, dau_ctrl.fd_mmu, DAU_MEM_REG_ADDR);
|
|
if (dau[unit]->reg < 0)
|
|
{
|
|
DBG(DBG_M_PD_DAU_ERR, "DAU mmap reg ERROR!\r\n");
|
|
return E_MEM;
|
|
}
|
|
|
|
/* 映射 PRPS 数据物理地址 */
|
|
dau[unit]->PRPS = (dau_prps_t*)mmap(0, DAU_MEM_PRPS_LEN, PROT_READ | PROT_WRITE, MAP_SHARED, dau_ctrl.fd_mmu, DAU_MEM_PRPS_ADDR);
|
|
if (dau[unit]->PRPS < 0)
|
|
{
|
|
DBG(DBG_M_PD_DAU_ERR, "DAU mmap PRPS ERROR!\r\n");
|
|
return E_MEM;
|
|
}
|
|
|
|
/* 映射原始数据物理地址 */
|
|
dau[unit]->original = (dau_original_t*)mmap(0, DAU_MEM_ORIGINAL_LEN, PROT_READ | PROT_WRITE, MAP_SHARED, dau_ctrl.fd_mmu, DAU_MEM_ORIGINAL_ADDR);
|
|
if (dau[unit]->original < 0)
|
|
{
|
|
DBG(DBG_M_PD_DAU_ERR, "DAU mmap original ERROR!\r\n");
|
|
return E_MEM;
|
|
}
|
|
|
|
return E_NONE;
|
|
}
|
|
|
|
/* 启动 DUA */
|
|
int32_t _dau_start(void)
|
|
{
|
|
uint8_t i = 0;
|
|
uint8_t j = 0;
|
|
|
|
/* DAU 上电. */
|
|
//system("echo system_wrapper.bin > /sys/class/fpga_manager/fpga0/firmware");
|
|
//sleep(3);
|
|
|
|
/* 设置为有效 */
|
|
for(i = 0; i < PD_DAU_SUM; i++)
|
|
{
|
|
if (!dau[i])
|
|
{
|
|
continue;
|
|
}
|
|
|
|
dau[i]->is_valid = TRUE;
|
|
}
|
|
|
|
for(i = 0; i < PD_DAU_SUM; i++)
|
|
{
|
|
if (!dau_is_valid(dau[i]))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
/* 寄存器映射 */
|
|
LD_E_RETURN(DBG_M_PD_DAU_ERR, _dau_reg_map(i));
|
|
dau[i]->reg->reg_global.GSCR = 0xFFFF0000 | DAU_CODE;
|
|
dau[i]->reg->reg_global.GSDPCR = 0;
|
|
|
|
/* 读通道校准系数. */
|
|
LD_E_RETURN(DBG_M_PD_DAU_ERR, _dau_param_adj_get(i));
|
|
|
|
/* 全局配置下发 */
|
|
dau_pps_mode_set();
|
|
dau_sync_mode_set();
|
|
dau_sync_fre_set();
|
|
dau_trend_inv_set();
|
|
|
|
/* 将端口配置同步到 DAU. */
|
|
for (j = 0; j < dau[i]->port_num; j++)
|
|
{
|
|
dau_port_filter_set(i, j);
|
|
dau_port_type_set(i, j);
|
|
|
|
dau[i]->port_state[j].denoise_auto = pd_config.config_port[i][j].denoise_auto;
|
|
dau[i]->port_state[j].denoise_variance = pd_config.config_port[i][j].denoise_variance;
|
|
}
|
|
|
|
/* 等待连接成功. */
|
|
if (DAU_CODE == ((dau[i]->reg->reg_global.GSCR & DAU_GSCR_CODE_Msk) >> DAU_GSCR_CODE_Pos))
|
|
{
|
|
dau[i]->is_connect = TRUE;
|
|
}
|
|
else
|
|
{
|
|
DBG(DBG_M_PD_DAU_ERR, "DAU start ERROR!\r\n");
|
|
return E_ERROR;
|
|
}
|
|
}
|
|
|
|
return E_NONE;
|
|
}
|
|
|
|
/* 配置保存函数. */
|
|
int _dau_config_save(vty_t* vty)
|
|
{
|
|
dau_t *dau_node = NULL;
|
|
int16_t i = 0;
|
|
uint8_t unit = 0;
|
|
|
|
/* 遍历所有 DAU. */
|
|
for (unit = 0; unit < PD_DAU_SUM; unit++)
|
|
{
|
|
dau_node = dau[unit];
|
|
if (!dau_node || dau_node->is_del)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
vty_out(vty, "dau %d port-num %d%s", unit + 1, dau_node->port_num, VTY_NEWLINE);
|
|
i++;
|
|
}
|
|
|
|
return i;
|
|
}
|
|
|
|
/* config模式配置保存函数: vty -- 相应的终端 */
|
|
int _dau_port_config_save(vty_t *vty, uint8_t unit, uint8_t port)
|
|
{
|
|
uint8_t field = 0;
|
|
char str[5] ={0};
|
|
|
|
field = pd_config.config_port[unit][port].port_type;
|
|
vty_out(vty, " port-type %s%s", dau_port_type_str[field], VTY_NEWLINE);
|
|
|
|
field = pd_config.config_port[unit][port].filter;
|
|
switch(field)
|
|
{
|
|
case CSG_FILTER_TYPE_HF:
|
|
snprintf(str, 5, "hf");
|
|
break;
|
|
case CSG_FILTER_TYPE_LF:
|
|
snprintf(str, 5, "lf");
|
|
break;
|
|
case CSG_FILTER_TYPE_FR:
|
|
snprintf(str, 5, "fr");
|
|
break;
|
|
case CSG_FILTER_TYPE_FF:
|
|
snprintf(str, 5, "ff");
|
|
break;
|
|
default:
|
|
snprintf(str, 5, "none");
|
|
break;
|
|
}
|
|
vty_out(vty, " filtrate-type %s%s", str, VTY_NEWLINE);
|
|
|
|
return E_NONE;
|
|
}
|
|
|
|
/* Interface functions -------------------------------------------------------*/
|
|
/* DAU 模块初始化. */
|
|
int32_t dau_handle_init(void)
|
|
{
|
|
int32_t rv = 0;
|
|
|
|
/* 注册命令行 */
|
|
cmd_install_element(CONFIG_NODE, &dau_add_cmd);
|
|
cmd_install_element(CONFIG_NODE, &no_dau_add_cmd);
|
|
|
|
cmd_install_element(PORT_NODE, &dau_port_type_cmd);
|
|
cmd_install_element(PORT_NODE, &dau_filter_type_cmd);
|
|
|
|
cmd_install_element(COMMON_NODE, &show_dau_status_all_cmd);
|
|
cmd_install_element(COMMON_NODE, &show_dau_vaule_cmd);
|
|
cmd_install_element(COMMON_NODE, &show_dau_adj_all_cmd);
|
|
cmd_install_element(COMMON_NODE, &show_dau_reg_all_cmd);
|
|
cmd_install_element(COMMON_NODE, &show_dau_reg_port_cmd);
|
|
|
|
/* 注册配置保存函数 */
|
|
rv = cmd_config_node_config_register(CONFIG_PRI_DAU, _dau_config_save);
|
|
if (rv != E_NONE)
|
|
{
|
|
log_err(LOG_DAU, "Command save register ERROR %d!", rv);
|
|
return rv;
|
|
}
|
|
|
|
rv = pd_port_cmd_config_register(PD_PORT_CMD_PRI_DAU, _dau_port_config_save);
|
|
if (rv != E_NONE)
|
|
{
|
|
log_err(LOG_DAU, "DAU port command save register ERROR %d!", rv);
|
|
return rv;
|
|
}
|
|
|
|
return E_NONE;
|
|
}
|
|
|
|
int32_t dau_handle_init_after(void)
|
|
{
|
|
struct sched_param param;
|
|
pthread_attr_t attr;
|
|
pthread_t pid;
|
|
int32_t rv = 0;
|
|
|
|
/* 初始化线程锁, 用于发包线程与首保线程同步. */
|
|
pthread_mutex_init(&dau_ctrl.mutex, NULL);
|
|
pthread_mutex_lock(&dau_ctrl.mutex);
|
|
|
|
/* 启动 DAU */
|
|
_dau_start();
|
|
|
|
/* 初始化趋势数据处理线程. */
|
|
/* 配置线程RR调度, 优先级25 */
|
|
pthread_attr_init(&attr);
|
|
param.sched_priority = 25;
|
|
pthread_attr_setschedpolicy(&attr, SCHED_RR);
|
|
pthread_attr_setschedparam(&attr, ¶m);
|
|
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
|
|
rv = pthread_create(&pid, &attr, _dau_trend_handle, NULL);
|
|
if (rv != 0)
|
|
{
|
|
log_err(LOG_DAU, "PD can't create DAU data pthread %d!", rv);
|
|
return E_SYS_CALL;
|
|
}
|
|
else
|
|
{
|
|
thread_m_add("PD_TREND_DATA", pid);
|
|
}
|
|
pthread_attr_destroy(&attr);
|
|
|
|
/* 初始化 DAU 报文处理线程. */
|
|
/* 配置线程RR调度, 优先级80 */
|
|
pthread_attr_init(&attr);
|
|
param.sched_priority = 80;
|
|
pthread_attr_setschedpolicy(&attr, SCHED_RR);
|
|
pthread_attr_setschedparam(&attr, ¶m);
|
|
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
|
|
rv = pthread_create(&pid, &attr, _dau_sec_data_handle, NULL);
|
|
if (rv != 0)
|
|
{
|
|
log_err(LOG_DAU, "PD can't create DAU data pthread %d!", rv);
|
|
return E_SYS_CALL;
|
|
}
|
|
else
|
|
{
|
|
thread_m_add("PD_DAU_DATA", pid);
|
|
}
|
|
pthread_attr_destroy(&attr);
|
|
|
|
/* 初始化 DAU 测试线程. */
|
|
/* 配置线程RR调度, 优先级25 */
|
|
pthread_attr_init(&attr);
|
|
param.sched_priority = 25;
|
|
pthread_attr_setschedpolicy(&attr, SCHED_RR);
|
|
pthread_attr_setschedparam(&attr, ¶m);
|
|
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
|
|
rv = pthread_create(&pid, &attr, _dau_test_handle, NULL);
|
|
if (rv != 0)
|
|
{
|
|
log_err(LOG_DAU, "PD can't create DAU data pthread %d!", rv);
|
|
return E_SYS_CALL;
|
|
}
|
|
else
|
|
{
|
|
thread_m_add("PD_DAU_TEST", pid);
|
|
}
|
|
pthread_attr_destroy(&attr);
|
|
|
|
return E_NONE;
|
|
}
|
|
|
|
|
|
/* 将 unit port 转换成 vport. */
|
|
int32_t dau_port_to_vport(uint8_t unit, uint8_t port)
|
|
{
|
|
uint8_t i = 0;
|
|
uint8_t vport = 0;
|
|
|
|
if (unit >= PD_DAU_SUM)
|
|
{
|
|
return E_BAD_PARAM;
|
|
}
|
|
|
|
for(i = 0; i < unit; i++)
|
|
{
|
|
if (!dau[i])
|
|
{
|
|
continue;
|
|
}
|
|
|
|
vport += dau[i]->port_num;
|
|
}
|
|
|
|
if (!dau[i])
|
|
{
|
|
return E_BAD_PARAM;
|
|
}
|
|
|
|
if (port >= dau[i]->port_num)
|
|
{
|
|
return E_BAD_PARAM;
|
|
}
|
|
|
|
return vport += port + 1;
|
|
}
|
|
|
|
/* 将 unit port 转换成 vport. */
|
|
int32_t dau_vport_to_port(uint8_t vport, uint8_t *unit, uint8_t *port)
|
|
{
|
|
uint8_t i = 0;
|
|
|
|
for(i = 0; i < PD_DAU_SUM; i++)
|
|
{
|
|
if (!dau[i])
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (vport <= dau[i]->port_num
|
|
&& vport != 0)
|
|
{
|
|
*unit = i;
|
|
*port = vport - 1;
|
|
return E_NONE;
|
|
}
|
|
else
|
|
{
|
|
vport -= dau[i]->port_num;
|
|
}
|
|
}
|
|
|
|
return E_BAD_PARAM;
|
|
}
|
|
|
|
/* 端口配置刷新对外接口. */
|
|
int32_t dau_port_filter_set(uint8_t unit, uint8_t port)
|
|
{
|
|
dau_t *dau_node = NULL;
|
|
uint32_t temp = 0;
|
|
|
|
if (unit >= PD_DAU_SUM)
|
|
{
|
|
return E_BAD_PARAM;
|
|
}
|
|
|
|
dau_node = dau[unit];
|
|
if (!dau_is_valid(dau_node))
|
|
{
|
|
return E_BAD_PARAM;
|
|
}
|
|
|
|
if (port >= dau_node->port_num)
|
|
{
|
|
return E_BAD_PARAM;
|
|
}
|
|
|
|
temp = pd_config.config_real[unit][port].filter_cfg;
|
|
switch(temp)
|
|
{
|
|
case CSG_FILTER_TYPE_FF:
|
|
temp = PD_FILTER_TYPE_FF;
|
|
break;
|
|
case CSG_FILTER_TYPE_FR:
|
|
temp = PD_FILTER_TYPE_FR;
|
|
break;
|
|
case CSG_FILTER_TYPE_LF:
|
|
temp = PD_FILTER_TYPE_LF;
|
|
break;
|
|
case CSG_FILTER_TYPE_HF:
|
|
temp = PD_FILTER_TYPE_HF;
|
|
break;
|
|
default:
|
|
return E_BAD_PARAM;
|
|
}
|
|
temp = (temp << DAU_CR_FT_Pos);
|
|
MODIFY_REG(dau_node->reg->reg_port[port].CR, DAU_CR_FT_Msk, temp);
|
|
|
|
return E_NONE;
|
|
}
|
|
|
|
/* 端口类型设置. */
|
|
int32_t dau_port_type_set(uint8_t unit, uint8_t port)
|
|
{
|
|
dau_t *dau_node = NULL;
|
|
uint32_t temp = 0;
|
|
|
|
if (unit >= PD_DAU_SUM)
|
|
{
|
|
return E_BAD_PARAM;
|
|
}
|
|
|
|
dau_node = dau[unit];
|
|
if (!dau_is_valid(dau_node))
|
|
{
|
|
return E_BAD_PARAM;
|
|
}
|
|
|
|
if (port >= dau_node->port_num)
|
|
{
|
|
return E_BAD_PARAM;
|
|
}
|
|
|
|
temp = (pd_config.config_port[unit][port].port_type << DAU_CR_PT_Pos);
|
|
MODIFY_REG(dau_node->reg->reg_port[port].CR, DAU_CR_PT_Msk, temp);
|
|
|
|
if (PD_PORT_TYPE_UHF == pd_config.config_port[unit][port].port_type)
|
|
{
|
|
dau_node->port_func[port] = &uhf_func;
|
|
}
|
|
else if(PD_PORT_TYPE_AE == pd_config.config_port[unit][port].port_type)
|
|
{
|
|
dau_node->port_func[port] = &uhf_func;
|
|
}
|
|
else if(PD_PORT_TYPE_HF == pd_config.config_port[unit][port].port_type)
|
|
{
|
|
dau_node->port_func[port] = &hf_func;
|
|
}
|
|
else
|
|
{
|
|
dau_node->port_func[port] = &uhf_func;
|
|
}
|
|
|
|
return E_NONE;
|
|
}
|
|
|
|
/* PPS 主备模式配置 */
|
|
int32_t dau_pps_mode_set(void)
|
|
{
|
|
dau_t *dau_node = NULL;
|
|
uint8_t unit = 0;
|
|
uint32_t temp = 0;
|
|
|
|
/* 自动 / 手动降噪. */
|
|
for(unit = 0; unit < PD_DAU_SUM; unit++)
|
|
{
|
|
dau_node = dau[unit];
|
|
if (!dau_is_valid(dau_node))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
temp = (pd_config.config.pps_mode << DAU_GCR_PPS_Pos);
|
|
MODIFY_REG(dau_node->reg->reg_global.GCR, DAU_GCR_PPS_Msk, temp);
|
|
}
|
|
|
|
return E_NONE;
|
|
}
|
|
|
|
/* 同步模式配置 */
|
|
int32_t dau_sync_mode_set(void)
|
|
{
|
|
dau_t *dau_node = NULL;
|
|
uint8_t unit = 0;
|
|
uint32_t temp = 0;
|
|
|
|
/* 自动 / 手动降噪. */
|
|
for(unit = 0; unit < PD_DAU_SUM; unit++)
|
|
{
|
|
dau_node = dau[unit];
|
|
if (!dau_is_valid(dau_node))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
temp = (pd_config.config.sync_mode << DAU_GCR_SYNC_Pos);
|
|
MODIFY_REG(dau_node->reg->reg_global.GCR, DAU_GCR_SYNC_Msk, temp);
|
|
}
|
|
|
|
return E_NONE;
|
|
}
|
|
|
|
/* 内同步频率配置 */
|
|
int32_t dau_sync_fre_set(void)
|
|
{
|
|
dau_t *dau_node = NULL;
|
|
uint8_t unit = 0;
|
|
uint32_t temp = 0;
|
|
|
|
/* 自动 / 手动降噪. */
|
|
for(unit = 0; unit < PD_DAU_SUM; unit++)
|
|
{
|
|
dau_node = dau[unit];
|
|
if (!dau_is_valid(dau_node))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
temp = (pd_config.config.power_frequency << DAU_GCR_OFRE_Pos);
|
|
MODIFY_REG(dau_node->reg->reg_global.GCR, DAU_GCR_OFRE_Msk, temp);
|
|
}
|
|
|
|
return E_NONE;
|
|
}
|
|
|
|
/* 趋势间隔配置 */
|
|
int32_t dau_trend_inv_set(void)
|
|
{
|
|
dau_t *dau_node = NULL;
|
|
uint8_t unit = 0;
|
|
uint32_t temp = 0;
|
|
|
|
/* 自动 / 手动降噪. */
|
|
for(unit = 0; unit < PD_DAU_SUM; unit++)
|
|
{
|
|
dau_node = dau[unit];
|
|
if (!dau_is_valid(dau_node))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
temp = ((pd_config.config.trend_period / 60) << DAU_GCR_TREND_Pos);
|
|
MODIFY_REG(dau_node->reg->reg_global.GCR, DAU_GCR_TREND_Msk, temp);
|
|
}
|
|
|
|
return E_NONE;
|
|
}
|
|
|
|
/* 获取工频同步状态. */
|
|
int32_t dau_power_frequency_state_get(void)
|
|
{
|
|
dau_t *dau_node = NULL;
|
|
uint8_t i = 0;
|
|
|
|
for(i = 0; i < PD_DAU_SUM; i++)
|
|
{
|
|
dau_node = dau[i];
|
|
if (!dau_is_valid(dau_node))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (!((dau_node->reg->reg_global.GSR & DAU_GSR_SYNC_Msk) >> DAU_GSR_SYNC_Pos))
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/* 获取工频周期. */
|
|
float dau_power_frequency_get(void)
|
|
{
|
|
dau_t *dau_node = NULL;
|
|
float temp = 100000000.00;
|
|
|
|
dau_node = dau[0];
|
|
if (!dau_is_valid(dau_node))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return dau_node->reg->reg_global.GPFPCCR ? (temp / dau_node->reg->reg_global.GPFPCCR) : 0;
|
|
}
|
|
|
|
/* 获取在线状态 */
|
|
uint8_t dau_connect_get(void)
|
|
{
|
|
dau_t *dau_node = NULL;
|
|
|
|
dau_node = dau[0];
|
|
if (!dau_is_valid(dau_node))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return dau[0]->is_connect;
|
|
}
|
|
|
|
/* 获取端口状态寄存器. */
|
|
int32_t dau_param_adj_save(void)
|
|
{
|
|
dau_t *dau_node = NULL;
|
|
dau_adj_t adj;
|
|
int fd = 0;
|
|
ssize_t len = 0;
|
|
uint8_t port = 0;
|
|
char cmd[128] = {0};
|
|
int32_t rv = E_NONE;
|
|
|
|
dau_node = dau[0];
|
|
if (!dau_is_valid(dau_node))
|
|
{
|
|
return E_NOT_FOUND;
|
|
}
|
|
|
|
/* 保存备份文件 */
|
|
snprintf(cmd, 128, "cp -rf %s %s", DAU_ADJ_FILE, DAU_ADJ_FILE_BAK);
|
|
system(cmd);
|
|
|
|
fd = open(DAU_ADJ_FILE, O_RDWR | O_CREAT | O_CREAT, 0777);
|
|
if (fd < 0 )
|
|
{
|
|
DBG(DBG_M_PD_DAU_ERR, "Open %s ERROR!\r\n", DAU_ADJ_FILE);
|
|
return E_SYS_CALL;
|
|
}
|
|
|
|
for(port = 0; port < PD_DAU_PORT_SUM; port++)
|
|
{
|
|
memcpy(&(adj.port[port]), dau[0]->reg->reg_port[port].ASPR, sizeof(dau_adj_port_t));
|
|
}
|
|
|
|
len = write(fd, &adj, sizeof(dau_adj_t));
|
|
if (len != sizeof(dau_adj_t))
|
|
{
|
|
DBG(DBG_M_PD_DAU_ERR, "Write %s len %d!\r\n", DAU_ADJ_FILE, len);
|
|
close(fd);
|
|
return E_SYS_CALL;
|
|
}
|
|
|
|
close(fd);
|
|
system("sync");
|
|
|
|
return rv;
|
|
}
|
|
|
|
/* 判断 DAU 是否有效. */
|
|
int32_t dau_is_valid(dau_t *dau_node)
|
|
{
|
|
if (!dau_node)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (!dau_node->is_valid)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/* 获取 DAU 版本号 */
|
|
char* dau_version_get(uint8_t unit, char *ver)
|
|
{
|
|
dau_t *dau_node = NULL;
|
|
int major, minor;
|
|
|
|
dau_node = dau[unit];
|
|
if (!dau_node)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
major = (dau_node->reg->reg_global.GSCR & DAU_GSCR_PRIMARY_Msk) >> DAU_GSCR_PRIMARY_Pos;
|
|
minor = (dau_node->reg->reg_global.GSCR & DAU_GSCR_SECONDARY_Msk) >> DAU_GSCR_SECONDARY_Pos;
|
|
sprintf(ver, "%d.%d", major, minor);
|
|
return ver;
|
|
}
|
|
|
|
/* 显示 DAU 状态. */
|
|
void dau_show(uint8_t unit)
|
|
{
|
|
dau_t *dau_node = NULL;
|
|
|
|
dau_node = dau[unit];
|
|
if (!dau_node)
|
|
{
|
|
return;
|
|
}
|
|
|
|
printh("DAU %d: \r\n", unit + 1);
|
|
printh(" Version: %d.%d\r\n", (dau_node->reg->reg_global.GSCR & DAU_GSCR_PRIMARY_Msk) >> DAU_GSCR_PRIMARY_Pos,
|
|
(dau_node->reg->reg_global.GSCR & DAU_GSCR_SECONDARY_Msk) >> DAU_GSCR_SECONDARY_Pos);
|
|
printh(" Mode: %s\r\n", (dau_node->reg->reg_global.GSR & DAU_GSR_MODE_Msk) >> DAU_GSR_MODE_Pos ? "master" : "slave");
|
|
printh(" Synchronization: %s\r\n", (dau_node->reg->reg_global.GSR & DAU_GSR_SYNC_Msk) >> DAU_GSR_SYNC_Pos ? "valid" : "invalid");
|
|
printh(" Power frequency period: %.2f\r\n", dau_power_frequency_get());
|
|
printh(" Power frequency count: %d\r\n", dau_node->reg->reg_global.GSDPCR);
|
|
printh(" Valid: %d\r\n\n", dau_node->is_valid);
|
|
|
|
return;
|
|
}
|
|
|
|
/* 显示 DAU 状态. */
|
|
void dau_show_value(uint8_t unit)
|
|
{
|
|
dau_t *dau_node = NULL;
|
|
uint8_t i = 0;
|
|
|
|
dau_node = dau[unit];
|
|
if (!dau_is_valid(dau_node))
|
|
{
|
|
return;
|
|
}
|
|
|
|
printh("DAU %d: \r\n", unit + 1);
|
|
printh(" 1 2 3 4 5 6 7 8\r\n ");
|
|
|
|
for(i = 0; i < dau_node->port_num; i++)
|
|
{
|
|
printh("%-05d ", dau_node->reg->reg_port[i].AVRO);
|
|
}
|
|
printh("\r\n ");
|
|
|
|
for(i = 0; i < dau_node->port_num; i++)
|
|
{
|
|
printh("%-05d ", (dau_node->reg->reg_port[i].AVRP & DAU_AVRP_AVR_Msk) >> DAU_AVRP_AVR_Pos);
|
|
}
|
|
printh("\r\n ");
|
|
|
|
for(i = 0; i < dau_node->port_num; i++)
|
|
{
|
|
printh("%-05d ", (dau_node->reg->reg_port[i].AVRP & DAU_AVRP_AVRA_Msk) >> DAU_AVRP_AVRA_Pos);
|
|
}
|
|
printh("\r\n\n");
|
|
|
|
return;
|
|
}
|
|
|
|
/* 显示 DAU 校准系数. */
|
|
void dau_show_adj(uint8_t unit)
|
|
{
|
|
dau_t *dau_node = NULL;
|
|
dau_reg_port_t *reg = NULL;
|
|
uint8_t port = 0;
|
|
|
|
dau_node = dau[unit];
|
|
if (!dau_node)
|
|
{
|
|
return;
|
|
}
|
|
|
|
printh("DAU %d: \r\n", unit + 1);
|
|
for(port = 0; port < dau_node->port_num; port++)
|
|
{
|
|
reg = &dau_node->reg->reg_port[port];
|
|
printh("%d | %05d %05d %05d | %05d %05d %05d | %05d %05d %05d |", port + 1, reg->AFR[0] & 0xFFFF, reg->AFR[0] >> 16, reg->ASPR[0],
|
|
reg->AFR[1] & 0xFFFF, reg->AFR[1] >> 16, reg->ASPR[1], reg->AFR[2] & 0xFFFF, reg->AFR[2] >> 16, reg->ASPR[2]);
|
|
printh(" %05d %05d %05d | %05d %05d %05d |\r\n", reg->AFR[3] & 0xFFFF, reg->AFR[3] >> 16, reg->ASPR[3],
|
|
reg->AFR[4] & 0xFFFF, reg->AFR[4] >> 16, reg->ASPR[4]);
|
|
}
|
|
printh("\r\n");
|
|
}
|
|
|
|
/* 显示 DAU 全局寄存器. */
|
|
void dau_show_reg(uint8_t unit)
|
|
{
|
|
dau_t *dau_node = NULL;
|
|
uint32_t *reg = NULL;
|
|
uint8_t num = 8;
|
|
uint8_t row = 0;
|
|
uint8_t col = 0;
|
|
uint8_t i = 0;
|
|
uint8_t j = 0;
|
|
|
|
dau_node = dau[unit];
|
|
if (!dau_node)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* 每行显示 16 个寄存器, 计算需要多少行 */
|
|
row = num >> 4;
|
|
if (num & 0x0f)
|
|
{
|
|
row++;
|
|
}
|
|
|
|
printh("DAU %d: \r\n", unit + 1);
|
|
for(i = 0; i < row; i++)
|
|
{
|
|
/* 计算有多少列 */
|
|
col = num - (i << 4);
|
|
col = col > 16 ? 16 : col;
|
|
printh("R ");
|
|
for(j = 0; j < col; j++)
|
|
{
|
|
printh("%-08x ", (i << 4) + j);
|
|
}
|
|
|
|
/* 打印寄存器值 */
|
|
reg = &dau_node->reg->reg_global.GSCR;
|
|
reg += (i << 4);
|
|
printh("\r\nV ");
|
|
for(j = 0; j < col; j++)
|
|
{
|
|
printh("%08x ", reg[j]);
|
|
}
|
|
printh("\r\n\n");
|
|
}
|
|
}
|
|
|
|
/* 显示 DAU 端口寄存器. */
|
|
void dau_show_reg_port(uint8_t unit, uint8_t port)
|
|
{
|
|
dau_t *dau_node = NULL;
|
|
uint32_t *reg = NULL;
|
|
uint8_t num = 36;
|
|
uint8_t row = 0;
|
|
uint8_t col = 0;
|
|
uint8_t i = 0;
|
|
uint8_t j = 0;
|
|
|
|
dau_node = dau[unit];
|
|
if (!dau_is_valid(dau_node))
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* 每行显示 16 个寄存器, 计算需要多少行 */
|
|
row = num >> 4;
|
|
if (num & 0x0f)
|
|
{
|
|
row++;
|
|
}
|
|
|
|
printh("DAU %d port %d: \r\n", unit + 1, port + 1);
|
|
for(i = 0; i < row; i++)
|
|
{
|
|
/* 计算有多少列 */
|
|
col = num - (i << 4);
|
|
col = col > 16 ? 16 : col;
|
|
printh("R ");
|
|
for(j = 0; j < col; j++)
|
|
{
|
|
printh("%-08x ", (i << 4) + j);
|
|
}
|
|
|
|
reg = &dau_node->reg->reg_port[port].CR;
|
|
reg += (i << 4);
|
|
printh("\r\nV ");
|
|
for(j = 0; j < col; j++)
|
|
{
|
|
printh("%08x ", reg[j]);
|
|
}
|
|
printh("\r\n\n");
|
|
}
|
|
}
|
|
|
|
#endif
|
|
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****/
|