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.

1190 lines
36 KiB
C

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*****************************************************************************
* 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>&copy; 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
#define _USE_MATH_DEFINES
/* 标准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 <math.h>
#include <time.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_dau.h"
#include "u-dma-buf-ioctl.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define DAU_CODE 0x0701
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
dau_ctrl_t dau_ctrl={0,0,};
dau_t *dau[PD_DAU_SUM];
int16_t test_data[20000];
/* Private function prototypes -----------------------------------------------*/
extern int32_t _dau_add(uint8_t unit, uint8_t port_num);
extern void _dau_del(uint8_t unit);
/* DAU 端口类型分类 */
//static const char *dau_port_type_str[PD_PORT_TYPE_COUNT] =
//{
// "",
// "uhf",
//};
/* DAU 端口状态分类. */
static const char *pd_port_status_str[PD_PORT_STATUS_COUNT] =
{
"disable",
"enable"
};
// /* 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;
// }
/* 显示 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;
}
/* 端口使能配置. */
CMD(pd_port_status,
pd_port_status_cmd,
"port status (enable|disable)",
"Port\n"
"Status\n"
"enable|disable\n")
{
uint8_t port_status = 0;
uint8_t unit = 0;
uint8_t port = 0;
uint32_t reg_value;
dau_t * dau_node = NULL;
int i=0;
/* 取出端口号. */
if (dau_vport_to_port(pd_port_node.param_num, &unit, &port) != E_NONE)
{
return CMD_ERR_NO_MATCH;
}
dau_node = dau[unit];
for(port_status = PD_PORT_DISABLE; port_status < PD_PORT_STATUS_COUNT; port_status++)
{
if (strncmp(argv[0], pd_port_status_str[port_status], strlen(pd_port_status_str[port_status])))
{
continue;
}
pd_config.config_port[unit][port].is_enbale = port_status;
for(i=0; i<PD_DAU_PORT_SUM; i++)
{
if(pd_config.config_port[unit][i].is_enbale == PD_PORT_ENABLE)
SET_BIT(pd_config.config.ch_en_mask, 0x1<<i);
else
CLEAR_BIT(pd_config.config.ch_en_mask, 0x1<<i);
}
if(dau_node->is_connect == TRUE)
{
reg_value = dau_node->reg->reg_global.port_enable;
if(port_status == PD_PORT_ENABLE)
{
SET_BIT(reg_value, 0x1<<port);
}
else if(port_status == PD_PORT_DISABLE)
{
CLEAR_BIT(reg_value, 0x1<<port);
}
dau_node->reg->reg_global.port_enable = reg_value;
pd_config.config.ch_en_mask = reg_value;
}
}
return CMD_SUCCESS;
}
/* 南瑞传输端口号设置. */
CMD(pd_port_sendnum,
pd_port_sendnum_cmd,
"sendport num <0-32>",
"Sendport\n"
"Num\n"
"Sendport number\n")
{
uint8_t send_port_num = 0;
uint8_t unit = 0;
uint8_t port = 0;
dau_t * dau_node = NULL;
/* 取出端口号. */
if (dau_vport_to_port(pd_port_node.param_num, &unit, &port) != E_NONE)
{
return CMD_ERR_NO_MATCH;
}
dau_node = dau[unit];
send_port_num = strtol(argv[0], NULL, 10);
pd_config.config_port[unit][port].send_port_num = send_port_num;
if(dau_node->is_connect == TRUE)
{
dau_node->reg->reg_port[port].ch_send_num = send_port_num;
}
return CMD_SUCCESS;
}
void time_get(uint32_t *timesVal, uint32_t *timeUsVal)
{
struct timeval tv = {0};
struct tm tptr = {0};
struct tm *p;
// 获取当前系统时间
if (gettimeofday(&tv, NULL) != 0)
{
perror("gettimeofday失败");
return; // 错误处理
}
// 将 tv.tv_sec 转换为 struct tm
p = localtime(&tv.tv_sec);
if (p == NULL)
{
perror("localtime失败");
return; // 错误处理
}
// 复制到 tptr与 time_set 保持一致)
tptr.tm_year = p->tm_year;
tptr.tm_mon = p->tm_mon;
tptr.tm_mday = p->tm_mday;
tptr.tm_hour = p->tm_hour;
tptr.tm_min = p->tm_min;
tptr.tm_sec = p->tm_sec;
// 转换为 time_t
time_t timestamp = mktime(&tptr);
if (timestamp == (time_t)-1)
{
perror("mktime失败");
return; // 错误处理
}
*timesVal = (uint32_t)timestamp;
*timeUsVal = (uint32_t)tv.tv_usec;
}
/* 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;
}
}
else
{
return E_NONE;
}
/* 初始化 DAU 结构体. */
dau_node->unit = unit;
dau_node->port_num = port_num;
dau_node->reg = NULL;
dau_node->adc_data = NULL;
dau_node->is_connect = FALSE;
dau[unit] = dau_node;
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_valid = FALSE;
}
/* 发送数据到后台通讯进程. */
int32_t _dau_msg_send_csg(uint32_t type, void *data, uint8_t port_idx)
{
uint32_t fifo_id;
pd_csg_msg_t up_msg;
/* 封装消息. */
up_msg.type = type;
up_msg.data = data;
if (type == PD_SEND_TYPE_ORIGINAL_DATA)
{
fifo_id = csg.fifo_real_image_id[port_idx];
}
else if (type == PD_SEND_TYPE_TREND)
{
fifo_id = csg.fifo_trend_id;
}
else
{
return E_ERROR;
}
/* 发送消息 */
if (fifo_write(fifo_id, (void*)(&up_msg), sizeof(pd_csg_msg_t)) != sizeof(pd_csg_msg_t))
{
printf("fifo %d write error\n", type);
return E_ERROR;
}
return E_NONE;
}
wave_additional_data_t* _dau_get_wave_addtion_data(char *frame, uint32_t frame_len)
{
if (NULL != frame || frame_len > ALL_ADDITIONAL_LEN)
return (wave_additional_data_t*)(frame + (frame_len - ALL_ADDITIONAL_LEN) * sizeof(uint16_t));
return NULL;
}
int _dau_write_channel_to_file(pd_original_port_t* channel, int channel_id)
{
int32_t data_size;
static uint32_t times = 0;
if (!channel) return -1;
//if (access("/mnt/nfs/devlog/wave", F_OK) )
if (times > 30)
return 0;
const char *dir_path = "/mnt/nfs/devlog";
if (access(dir_path, F_OK) != 0)
{
printf("Directory does not exist.\n");
return -1;
}
// 生成文件名
char filename[256];
snprintf(filename, sizeof(filename), "%s/channel_%d_%02d.bin", dir_path, channel_id, times++);
// 打开文件
int file_fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (file_fd == -1)
{
perror("Failed to open file");
return -1;
}
// 先写入通道结构体信息
ssize_t bytes_written = write(file_fd, channel, sizeof(pd_original_port_t));
if (bytes_written != sizeof(pd_original_port_t))
{
perror("Failed to write channel info");
close(file_fd);
return -1;
}
// 更新数据大小
data_size = channel->single_frame_length * sizeof(uint16_t);
// 写入通道数据
for (int i = 0; i < channel->frame_numbers; i++)
{
uint32_t offset = i * channel->single_frame_length * sizeof(uint16_t);
bytes_written = write(file_fd, channel->original_pointer + offset , data_size);
if (bytes_written != (ssize_t)data_size)
{
perror("Failed to write channel data");
close(file_fd);
return -1;
}
}
close(file_fd);
printf("Channel written to file: %s\n", filename);
return 0;
}
/* 原始波形数据处理. */
void _dau_data_original(void)
{
dau_t *dau_node = NULL;
uint8_t unit = 0;
uint8_t port = 0;
//struct timeval tv = {0};
uint64_t offset_addr = 0;
// uint32_t time_s;
// uint32_t time_us;
pd_original_port_t *pd_original_port = NULL;
// uint64_t sync_for_cpu = 1;
// u_dma_buf_ioctl_sync_args sync_args;
//static struct timespec trend_ts = {0};
//static pd_trend_t trend[PD_DAU_PORT_SUM] = {0};
//pd_trend_t *ptrend = NULL;
wave_additional_data_t *header = NULL;
pd_trend_port_t *ptrend = NULL;
static uint16_t count[PD_DAU_PORT_SUM][360] = {0};
/* 数据处理 */
for(unit = 0; unit < PD_DAU_SUM; unit++)
{
dau_node = dau[unit];
if (!dau_is_valid(dau_node))
{
continue;
}
for(port = 0; port < PD_DAU_PORT_SUM; port++)
{
if(pd_config.config_port[unit][port].is_enbale == TRUE)
{
csg.new_data_flag[port] = TRUE;
//gettimeofday(&tv, NULL);
offset_addr = dau_node->reg->reg_port[port].data_start_addr;
if(offset_addr >= DAU_MEM_ORIGINAL_LEN)
{
DBG(DBG_M_PD_DAU_ERR, "dau %dport data addr over max area!\r\n",port);
continue;
}
/*申请原始数据内存*/
pd_original_port = XMALLOC_Q(MTYPE_CSG, sizeof(pd_original_port_t));
if (!pd_original_port)
{
DBG(DBG_M_PD_DAU_ERR, "dau %dport data malloc failed!\r\n",port);
continue;
}
pd_original_port->data_vaild = dau_node->reg->reg_port[port].data_valid;
pd_original_port->original_pointer = dau_node->adc_data + offset_addr; //每个通道的波形数据起始映射地址赋值
// printf("offset:%x\n",offset_addr);
pd_original_port->interrupt_count++;
pd_original_port->total_pulse_nums = dau_node->reg->reg_port[port].total_pulse_nums;
pd_original_port->frame_numbers = dau_node->reg->reg_port[port].wave_nums;
pd_original_port->single_frame_length = dau_node->reg->reg_port[port].signle_wave_length;
pd_original_port->ground_noise = dau_node->reg->reg_port[port].ground_noise;
pd_original_port->century_second = dau_node->reg->reg_global.b_time_epoch_sec;
if(pd_original_port->single_frame_length != DEFAULT_SAMPLE_NUM)
{
pd_original_port->data_vaild = FALSE;
}
//_dau_write_channel_to_file(pd_original_port, port);
// time_get(&time_s, &time_us);
// pd_original_port->century_second = time_s;
// pd_original_port->nano_second = time_us * 1000;
if(pd_original_port->data_vaild)
{
// /* 设置同步区域PL修改了数据 */
// sync_args.offset = offset_addr;
// if(pd_original_port->frame_numbers > 20)
// {
// sync_args.size = 20*pd_original_port->single_frame_length;
// }
// else
// {
// sync_args.size = pd_original_port->frame_numbers*pd_original_port->single_frame_length;
// }
// sync_args.flags = 0;
// SET_U_DMA_BUF_IOCTL_FLAGS_SYNC_DIR(&sync_args, 2); /* DMA_FROM_DEVICE */
// SET_U_DMA_BUF_IOCTL_FLAGS_SYNC_CMD(&sync_args, U_DMA_BUF_IOCTL_FLAGS_SYNC_CMD_FOR_CPU);
// if (ioctl(dau_ctrl.fd_data_mmu, U_DMA_BUF_IOCTL_SET_SYNC, &sync_args) < 0) {
// perror("set sync area failed \n");
// }
// /* 在 PL 修改数据后,同步到 CPU */
// sync_for_cpu = 1;
// if (ioctl(dau_ctrl.fd_data_mmu, U_DMA_BUF_IOCTL_SET_SYNC_FOR_CPU, &sync_for_cpu) < 0) {
// perror("sync CPU failed \n");
// }
#if 0
struct timespec ts;
// 获取当前时间
if (clock_gettime(CLOCK_REALTIME, &ts) != 0)
{
perror("clock_gettime");
}
//image_head->century_second = ts.tv_sec;
//image_head->nanosecond = ts.tv_nsec;
#endif
#if 1
if (pd_data.trend_port[port] == NULL)
{
pd_data.trend_port[port] = XMALLOC_Q(MTYPE_CSG, sizeof(pd_trend_port_t));
if (!pd_data.trend_port[port])
{
DBG(DBG_M_PD_DAU_ERR, "dau %dport data malloc failed!\r\n",port);
continue;
}
memset(pd_data.trend_port[port], 0, sizeof(pd_trend_port_t));
}
ptrend = pd_data.trend_port[port];
ptrend->pulse_num += pd_original_port->total_pulse_nums;
#endif
for (int i = 0; i < pd_original_port->frame_numbers; i++)
{
char *data_point = NULL;
data_point = (char*)(pd_original_port->original_pointer) + (i * pd_original_port->single_frame_length * sizeof(int16_t));
header = _dau_get_wave_addtion_data(data_point, pd_original_port->single_frame_length);
DBG(DBG_M_PD_DAU_SEND, "port[%d]frame_numbers=%d total_pulse_nums=%d phase=%d,noise=%d,max=%d,pt_frame_num=%d,time=%ld %ld.%ld\r\n", port, pd_original_port->frame_numbers,
pd_original_port->total_pulse_nums, header->phase, header->noise, header->max, header->pt_frame_num, pd_original_port->century_second, header->epoch_sec, header->nano_sec);
if (header->max > ptrend->pulse_max)
ptrend->pulse_max = header->max;
ptrend->pulse_avg += header->max;
ptrend->noise += abs(header->noise);
if (ptrend->century_second == 0)
{
ptrend->century_second = pd_original_port->century_second;
}
if (header->phase >= 360)
{
DBG(DBG_M_PD_DAU_ERR,"phase error: %d\r\n", header->phase);
}
else
{
count[port][header->phase]++;
}
}
#if 1
//if (ptrend->century_second + pd_config.config.trend_up_period < header->epoch_sec)
if (ptrend->century_second + pd_config.config.trend_up_period < pd_original_port->century_second)
{
ptrend->pulse_avg /= (int32_t)ptrend->pulse_num;
ptrend->noise /= ptrend->pulse_num;
ptrend->port = port;
int max_count = 0;
int max_phase = 0;
for (int i = 0; i < 360; i++)
{
if (count[port][i] > max_count)
{
max_count = count[port][i];
max_phase = i;
}
}
ptrend->phase = max_phase;
DBG(DBG_M_PD_DAU, "port=%d pulse_num=%d pulse_max=%d pulse_avg=%d noise=%d phase=%d\r\n",
port, ptrend->pulse_num, ptrend->pulse_max, ptrend->pulse_avg, ptrend->noise, ptrend->phase);
if (_dau_msg_send_csg(PD_SEND_TYPE_TREND, (void *)pd_data.trend_port[port], port) != E_NONE)
{
DBG(DBG_M_PD_DAU_ERR, "send dau %dport data to fifo err!\r\n",port);
XFREE(MTYPE_CSG, ptrend);
}
pd_data.trend_port[port] = NULL;
memset(count[port], 0, sizeof(count[port]));
}
#endif
}
if (_dau_msg_send_csg(PD_SEND_TYPE_ORIGINAL_DATA, (void *)pd_original_port, port) != E_NONE)
{
// DBG(DBG_M_PD_DAU_ERR, "send dau %dport data to fifo err!\r\n",port);
XFREE(MTYPE_CSG, pd_original_port);
}
}
}
}
}
int _dau_wait_irq(int fd)
{
int ret = ioctl(fd, IOCTL_IRQ_WAIT);
return ret;
}
int32_t _dau_interrupt_init(void)
{
if (dau_ctrl.fd_adc_int != 0)
{
return E_NONE;
}
dau_ctrl.fd_adc_int = open("/dev/adc_interrupt_0", O_RDWR);
return dau_ctrl.fd_adc_int;
}
// 判断是否为闰年
int is_leap_year(int year) {
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
// 根据一年中的天数计算月日
void doy_to_date(struct tm *tmpr, uint16_t btime[]) {
// 正常年份每月的天数
int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// 输入年份范围检查和默认值设置
// 如果 btime[0] 不在 [10, 100] 范围内,则使用固定默认时间
// if (btime[0] > 100 || btime[0] < 10) {
// tmpr->tm_year = 2010 - 1900; // 2010年
// tmpr->tm_mon = 1 - 1; // 1月 (tm_mon 是 0-11)
// tmpr->tm_mday = 1; // 1日
// tmpr->tm_hour = 0;
// tmpr->tm_min = 0;
// tmpr->tm_sec = 0;
// tmpr->tm_isdst = 0; // 不考虑夏令时
// return;
// }
int year = btime[0] + 2000;
// 如果是闰年,二月有 29 天
if (is_leap_year(year)) {
days_in_month[1] = 29;
}
int remaining_days = btime[1]; // 一年中的第几天 (1-365或366)
int mon = 0; // 月份 (0-11)
int day = 0; // 日期 (1-31)
// 循环查找月份和日期
for (int i = 0; i < 12; i++) {
if (remaining_days <= days_in_month[i]) {
day = remaining_days;
mon = i; // 0-11 表示月份
break;
}
remaining_days -= days_in_month[i];
}
// 如果 remaining_days 经过循环后仍然大于 0说明 btime[1] 超出了一年的天数范围
// 可以在这里添加错误处理,例如设置一个无效日期或打印警告
// if (remaining_days > 0) {
// tmpr->tm_year = 2010 - 1900; // 2010年
// tmpr->tm_mon = 1 - 1; // 1月 (tm_mon 是 0-11)
// tmpr->tm_mday = 1; // 1日
// tmpr->tm_hour = 0;
// tmpr->tm_min = 0;
// tmpr->tm_sec = 0;
// tmpr->tm_isdst = 0; // 不考虑夏令时
// return;
// }
tmpr->tm_year = year - 1900; // tm_year 是从 1900 年开始计算的年份差
tmpr->tm_mon = mon; // tm_mon 是 0-11
tmpr->tm_mday = day; // tm_mday 是 1-31
tmpr->tm_hour = btime[2];
tmpr->tm_min = btime[3];
tmpr->tm_sec = btime[4];
tmpr->tm_isdst = 0; // 不考虑夏令时
}
/* DAU 数据处理函数. */
void *_dau_data_handle(void *arg)
{
uint32_t i = 0;
// uint16_t time[5];
// uint32_t now_sec,last_sec;
// struct tm tm_data = {0,};
// int year,mon,day,hour,min,sec;
// struct timeval start, end;
/* 等待初始化完成 */
while(!is_system_init)
{
usleep(100000);
}
// gettimeofday(&start, NULL);
// last_sec = dau[0]->reg->reg_global.b_time_sec;
while(1)
{
if (!dau_is_valid(dau[0]))
{
continue;
}
/* 等待 DAU 数据准备完成. */
_dau_wait_irq(dau_ctrl.fd_adc_int);
// gettimeofday(&end, NULL);
// printf("int time:%ldus\n", (end.tv_sec - start.tv_sec) * 1000000 + end.tv_usec - start.tv_usec);
// start = end;
if(i < 3)
{
i++;
continue;
}
// now_sec = dau[0]->reg->reg_global.b_time_sec;
// if(now_sec != last_sec)
// {
// time[0] = dau[0]->reg->reg_global.b_time_year;
// time[1] = dau[0]->reg->reg_global.b_time_day;
// time[2] = dau[0]->reg->reg_global.b_time_hour;
// time[3] = dau[0]->reg->reg_global.b_time_min;
// time[4] = now_sec;
// doy_to_date(&tm_data, time);
// year = tm_data.tm_year + 1900;
// mon = tm_data.tm_mon;
// day = tm_data.tm_mday;
// hour = tm_data.tm_hour;
// min = tm_data.tm_min;
// sec = tm_data.tm_sec;
// printf("year=%d,mon=%d,day=%d,hour=%d,min=%d,sec=%d\n",year,mon,day,hour,min,sec);
// }
// last_sec = now_sec;
// /* 数据处理 */
_dau_data_original();
}
return NULL;
}
/* dau 寄存器物理地址映射 */
int32_t _dau_reg_map(uint8_t unit)
{
dau_ctrl.fd_reg_mmu = open("/dev/mem", O_RDWR|O_SYNC);
dau_ctrl.fd_data_mmu = open("/dev/mem", O_RDWR|O_SYNC);
/* 映射参数设置寄存器 */
dau[unit]->reg = (dau_reg_t*)mmap(NULL, DAU_MEM_REG_LEN, PROT_READ | PROT_WRITE, MAP_SHARED, dau_ctrl.fd_reg_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;
}
/* 映射端口信息读取寄存器 */
dau[unit]->adc_data = (char *)mmap(NULL, DAU_MEM_ORIGINAL_LEN, PROT_READ | PROT_WRITE, MAP_SHARED, dau_ctrl.fd_data_mmu, DAU_MEM_ORIGINAL_ADDR);
if (dau[unit]->adc_data < 0)
{
DBG(DBG_M_PD_DAU_ERR, "DAU mmap original ERROR!\r\n");
return E_MEM;
}
return E_NONE;
}
void _dau_set_time(uint32_t tval)
{
int i;
for(i = 0; i < PD_DAU_SUM; i++)
{
if (!dau_is_valid(dau[i]))
{
continue;
}
//dau_t * dau_node = dau[0];
//if (dau_node->is_connect == TRUE)
{
if (IS_BITMAP_SET(pd_config.config.pt_B_sync_mode, PD_BIT_BCODE))
{
dau[i]->reg->reg_global.ps_epoch_sec = tval;
printf("####Z# time:%d\r\n", tval);
}
}
}
}
void dau_mode_set(uint8_t unit)
{
uint32_t ver_info;
uint32_t reg_value;
uint8_t idx = 0;
ver_info = dau[unit]->reg->reg_global.ver_num;
printf("ver_info=%08x\r\n",ver_info);
dau[unit]->reg->reg_global.sample_nums = pd_config.config.trigger_sample_nums; //采样个数
dau[unit]->reg->reg_global.sample_interrupt_intveal_us = pd_config.config.interrupt_interval; //采样中断间隔2ms一次
dau[unit]->reg->reg_global.trig_gap = pd_config.config.trig_gap;
dau[unit]->reg->reg_global.trig_location = pd_config.config.trig_location;
dau[unit]->reg->reg_global.trig_threshold = pd_config.config.trig_threshold;
dau[unit]->reg->reg_global.pt_B_sync_mode = pd_config.config.pt_B_sync_mode;
dau[unit]->reg->reg_global.mv_factor = DEFAULT_FACTOR_MV;
dau[unit]->reg->reg_global.irigB_polarity = pd_config.config.irigB_polarity;
dau[unit]->reg->reg_global.ch_type = DEFAULT_CH_TYPE;
dau[unit]->reg->reg_global.unit = DEFAULT_CH_UNIT;
//dau_t * dau_node = dau[0];
//if (dau_node->is_connect == TRUE)
{
if (IS_BITMAP_SET(pd_config.config.pt_B_sync_mode, PD_BIT_BCODE))
{
dau[unit]->reg->reg_global.ps_epoch_sec = time(NULL);
printf("####Z# time:%ld\r\n", time(NULL));
}
}
reg_value = dau[unit]->reg->reg_global.port_enable;
for(idx=0; idx<PD_DAU_PORT_SUM; idx++)
{
if(pd_config.config_port[unit][idx].is_enbale == PD_PORT_ENABLE)
{
SET_BIT(reg_value, 0x1<<idx);
}
else
{
CLEAR_BIT(reg_value, 0x1<<idx);
}
dau[unit]->reg->reg_port[idx].ch_send_num = pd_config.config_port[unit][idx].send_port_num;
}
dau[unit]->reg->reg_global.port_enable = reg_value;
}
/* 启动 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_mode_set(i);
/* 中断初始化 */
_dau_interrupt_init();
dau[i]->is_connect = TRUE;
}
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)
// {
// return FALSE;
// }
// 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;
field = pd_config.config_port[unit][port].is_enbale;
vty_out(vty, " port status %s%s", pd_port_status_str[field], VTY_NEWLINE);
field = pd_config.config_port[unit][port].send_port_num;
vty_out(vty, " sendport num %u%s", field, 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(COMMON_NODE, &show_dau_status_all_cmd);
cmd_install_element(PORT_NODE, &pd_port_status_cmd);
cmd_install_element(PORT_NODE, &pd_port_sendnum_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;
// int i=0;
// double sample_rate = 5e9; // 5 GHz
// double duration = 4e-6; // 2 microseconds
// double amplitude = 10000; // 2 mV -> volts
// double frequency = 600e6; // 600 MHz
// // 计算总采样点数
// int num_samples = (int)(sample_rate * duration);
// printf("Number of samples: %d\n", num_samples);
// for(i=0; i<num_samples; i++)
// {
// // test_data[i] = (uint16_t)(sin(2*M_PI*(double)i/100.0)*1000+3000);
// double t = i / sample_rate; // 时间点(秒)
// double value = amplitude * sin(2 * M_PI * frequency * t); // 正弦波
// test_data[i] = (int16_t)value;
// }
/* 初始化线程锁, 用于发包线程与首保线程同步. */
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 = 90;
pthread_attr_setschedpolicy(&attr, SCHED_RR);
pthread_attr_setschedparam(&attr, &param);
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
rv = pthread_create(&pid, &attr, _dau_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_TREND_DATA", 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;
}
/* 获取在线状态 */
uint8_t dau_connect_get(void)
{
return dau[0]->is_connect;
}
// /* 获取端口状态寄存器. */
// int32_t dau_param_adj_save(uint8_t unit)
// {
// dau_adj_t adj;
// int fd = 0;
// ssize_t len = 0;
// uint8_t port = 0;
// char cmd[128] = {0};
// int32_t rv = E_NONE;
// 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[unit]->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);
// /* 保存备份文件 */
// snprintf(cmd, 128, "cp -rf %s %s", DAU_ADJ_FILE, DAU_ADJ_FILE_BAK);
// system(cmd);
// 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 状态. */
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(" Valid: %d\r\n\n", dau_node->is_valid);
return;
}
/* 显示 DAU 状态. */
void dau_show_value(uint8_t unit)
{
dau_t *dau_node = NULL;
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 ");
return;
}
#endif
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****/