/*****************************************************************************
* 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
*
*
© COPYRIGHT(c) 2021 LandPower
*
* 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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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; iis_connect == TRUE)
{
reg_value = dau_node->reg->reg_global.port_enable;
if(port_status == PD_PORT_ENABLE)
{
SET_BIT(reg_value, 0x1<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; idxreg->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= 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 ****/