Browse Source

修改 : 对接开入量数据;

lch 8 months ago
parent
commit
81469be793

+ 4 - 1
README.md

@@ -43,7 +43,7 @@
 
 # 202512(08-14)
 01. 修改 : 网口的个数和对应的定值;
-   
+
 # 202512(15-21)
 01. 修改 : 南网定值;
 02. 修改 : qu16、qs16、qu08、qs08数据类型为int,以适配点表文件中对应数据类型的偏移是按32位的。
@@ -51,3 +51,6 @@
 04. 修复 : rt_get_netcard_id_from_socket函数中ip转换处理问题。
 05. 修改 : 直流数据对接;
 06. 增加 : led资源;
+
+# 202512(22-28)
+01. 修改 : 对接开入量数据;

+ 2 - 2
app_public/fuxi_public/fuxi_bsp/include/bspconfig.h

@@ -35,7 +35,7 @@
 #define EQU_SLOT_HMI			2	// 面板
 
 #define EQU_SLOT_AC_BEGIN		1	// 采样板起始槽位
-#define EQU_SLOT_AC_NUM			2	// 一个装置支持AC板的最大槽数。1 -> 2 DTUv5采用两块采样板
+#define EQU_SLOT_AC_NUM			1	// 一个装置支持AC板的最大槽数。1 -> 2 DTUv5采用两块采样板
 #define EQU_SLOT_AC_CHN			16   // 每个槽中支持的最大AC通道数
 #define EQU_DB_YX_NUM			32	// 数据总线长度
 
@@ -160,7 +160,7 @@
 #define CFG_ADC_OS_NUM				(1<<CFG_ADC_OS_BASE)	// 过采样倍数
 
 #define CFG_ADC_CHANNEL				16					// ADC采样的通道数
-#define CFG_ADC_CHANNEL_DC			1					// 直流ADC通道数量
+#define CFG_ADC_CHANNEL_DC			2					// 直流ADC通道数量
 #define CFG_ADC_CHANNEL_ALL			(CFG_ADC_CHANNEL + CFG_ADC_CHANNEL_DC) // 所有通道数
 #define CFG_ADC_CHANNEL_ZERO		(CFG_ADC_CHANNEL_ALL)	// 全0通道索引
 

+ 6 - 0
app_public/fuxi_public/fuxi_bsp/include/dido.h

@@ -32,6 +32,7 @@ struct ts_index
 
 struct di
 {
+	int bInited;	// 是否初始化
 	u32 value[2];	// 开入值
 	u32 inv[2];		// 是否反转
 
@@ -91,6 +92,7 @@ struct do_struct
 
 /*------------------------------ 全局变量 -------------------------------------
 */
+extern u8 g_di_slot;
 extern struct di g_di[];
 extern u8 dido_buf[128];
 extern struct di_struct g_di_st[EQU_SLOT_NUM_MAX][DIDO_MAX_DI_PER_SLOT];  
@@ -119,6 +121,10 @@ int dido_auto_test(char *buf,int num);
 int dido_single_test(u8 slot, u8 point);
 int dido_test(void);
 int dido_do_kz(int on, unsigned int i);
+#if !defined CPU_FUXI
+int dido_di_update(uint32_t _value_new, uint8_t _index, struct timespec *ts);
+#endif
+int get_shm_didata(void);
 
 #endif //_DIDO_H
 

+ 5 - 1
app_public/fuxi_public/fuxi_bsp/include/equ.h

@@ -65,6 +65,7 @@
 #define BOARD_TYPE_FUXI_DI          30   // 开入板
 #define BOARD_TYPE_FUXI_DO          31   // 开出板
 #define BOARD_TYPE_FUXI_AC          32   // 采样板
+#define BOARD_TYPE_FUXI_24LED		33	 // 液晶面板
 
 #define BOARD_TYPE_RS_STATUS		64	// 状态板
 #define BOARD_TYPE_LCD_16LED		65	// 液晶面板
@@ -305,7 +306,10 @@ u32 equ_get_slot_by_type(u8 type);
 u16 equ_di_to_sw(u8 slot,u8 no);
 char * equ_di_name(u8 slot,u8 no);
 u8   equ_di_type(u8 slot,u8 no);  //根据板卡和序号,返回遥信类型
-u8  equ_pub_di_type(u8 slot,u8 no) ;
+u8  equ_pub_di_type(u8 slot,u8 no);
+#ifdef CPU_FUXI
+int equ_init_rv_di(void);
+#endif
 #endif //_EQU_H
 
 /*------------------------------ 文件结束 -------------------------------------

+ 3 - 1
app_public/fuxi_public/fuxi_bsp/include/equ_fuxi.h

@@ -23,9 +23,11 @@
 */
 extern int 	g_ui_freq[CFG_FREQ_NUM];	// 记录频率对应UI通道的索引值
 
-int equ_init_later(void);
+int equ_init_di(void);
 
+#ifdef BSP_CAN_ENABLE
 int equ_board_info_update(int can_bus,u8 * frame);
+#endif
 
 int equ_ac_channel_is_ok(u32 index);
 

+ 0 - 1
app_public/fuxi_public/fuxi_bsp/include/gpio.h

@@ -55,7 +55,6 @@ unsigned int gpio_get_wirelessin(void);
 unsigned int gpio_get_version(void);
 unsigned int gpio_get_addr(void);
 
-// void gpio_watchdog_reset(void);
 void _led_run_err(void);
 void esam_power_ctrl(int on);
 

+ 0 - 73
app_public/fuxi_public/fuxi_bsp/include/gpio_def.h

@@ -1,73 +0,0 @@
-#ifndef __GPIO_DEF_H
-#define	__GPIO_DEF_H
-
-#define GPIO_A_H(x)			do{MCF_GPIO_PPDSDR_A   = (unsigned char) (1UL << x);}while(0)
-#define GPIO_A_L(x)			if(0)////do{MCF_GPIO_PCLRR_A    = (unsigned char)~(1UL << x);}while(0)
-#define GPIO_A_O(x)			do{MCF_GPIO_PDDR_A    |= (unsigned char) (1UL << x);}while(0)
-#define GPIO_A_I(x)			do{MCF_GPIO_PDDR_A    &= (unsigned char)~(1UL << x);}while(0)
-#define GPIO_A_S(x)			(MCF_GPIO_PPDSDR_A & (1UL << x))
-
-
-#define GPIO_B_H(x)			do{MCF_GPIO_PPDSDR_B   = (unsigned char) (1UL << x);}while(0)
-#define GPIO_B_L(x)			if(0)////do{MCF_GPIO_PCLRR_B    = (unsigned char)~(1UL << x);}while(0)
-#define GPIO_B_O(x)			do{MCF_GPIO_PDDR_B    |= (unsigned char) (1UL << x);}while(0)
-#define GPIO_B_I(x)			do{MCF_GPIO_PDDR_B    &= (unsigned char)~(1UL << x);}while(0)
-#define GPIO_B_S(x)			(MCF_GPIO_PPDSDR_B & (1UL << x))
-
-#define GPIO_C_H(x)			if(0)////do{MCF_GPIO_PPDSDR_C   = (unsigned char) (1UL << x);}while(0)
-#define GPIO_C_L(x)			if(0)////do{MCF_GPIO_PCLRR_C    = (unsigned char)~(1UL << x);}while(0)
-#define GPIO_C_O(x)			if(0)////do{MCF_GPIO_PDDR_C    |= (unsigned char) (1UL << x);}while(0)
-#define GPIO_C_I(x)			if(0)////do{MCF_GPIO_PDDR_C    &= (unsigned char)~(1UL << x);}while(0)
-#define GPIO_C_S(x)			x////(MCF_GPIO_PPDSDR_C & (1UL << x))
-
-#define GPIO_D_H(x)			if(0)//do{MCF_GPIO_PPDSDR_D   = (unsigned char) (1UL << x);}while(0)
-#define GPIO_D_L(x)			if(0)////do{MCF_GPIO_PCLRR_D    = (unsigned char)~(1UL << x);}while(0)
-#define GPIO_D_O(x)			do{MCF_GPIO_PDDR_D    |= (unsigned char) (1UL << x);}while(0)
-#define GPIO_D_I(x)			do{MCF_GPIO_PDDR_D    &= (unsigned char)~(1UL << x);}while(0)
-#define GPIO_D_S(x)			(MCF_GPIO_PPDSDR_D & (1UL << x))
-
-#define GPIO_E_H(x)			x//do{MCF_GPIO_PPDSDR_E   = (unsigned char) (1UL << x);}while(0)
-#define GPIO_E_L(x)			if(0)////do{MCF_GPIO_PCLRR_E    = (unsigned char)~(1UL << x);}while(0)
-#define GPIO_E_O(x)			do{MCF_GPIO_PDDR_E    |= (unsigned char) (1UL << x);}while(0)
-#define GPIO_E_I(x)			do{MCF_GPIO_PDDR_E    &= (unsigned char)~(1UL << x);}while(0)
-#define GPIO_E_S(x)			(MCF_GPIO_PPDSDR_E & (1UL << x))
-
-#define GPIO_F_H(x)			if(0)//do{MCF_GPIO_PPDSDR_F   = (unsigned char) (1UL << x);}while(0)
-#define GPIO_F_L(x)			if(0)////do{MCF_GPIO_PCLRR_F    = (unsigned char)~(1UL << x);}while(0)
-#define GPIO_F_O(x)			if(0)//do{MCF_GPIO_PDDR_F    |= (unsigned char) (1UL << x);}while(0)
-#define GPIO_F_I(x)			if(0)//do{MCF_GPIO_PDDR_F    &= (unsigned char)~(1UL << x);}while(0)
-#define GPIO_F_S(x)			x//(MCF_GPIO_PPDSDR_F & (1UL << x))
-
-#define GPIO_G_H(x)			x//do{MCF_GPIO_PPDSDR_G   = (unsigned char) (1UL << x);}while(0)
-#define GPIO_G_L(x)			x//do{MCF_GPIO_PCLRR_G    = (unsigned char)~(1UL << x);}while(0)
-#define GPIO_G_O(x)			x//do{MCF_GPIO_PDDR_G    |= (unsigned char) (1UL << x);}while(0)
-#define GPIO_G_I(x)			x//do{MCF_GPIO_PDDR_G    &= (unsigned char)~(1UL << x);}while(0)
-#define GPIO_G_S(x)			x//(MCF_GPIO_PPDSDR_G & (1UL << x))
-
-#define GPIO_H_H(x)			x//do{MCF_GPIO_PPDSDR_H   = (unsigned char) (1UL << x);}while(0)
-#define GPIO_H_L(x)			x//do{MCF_GPIO_PCLRR_H    = (unsigned char)~(1UL << x);}while(0)
-#define GPIO_H_O(x)			x//do{MCF_GPIO_PDDR_H    |= (unsigned char) (1UL << x);}while(0)
-#define GPIO_H_I(x)			x//do{MCF_GPIO_PDDR_H    &= (unsigned char)~(1UL << x);}while(0)
-#define GPIO_H_S(x)			(MCF_GPIO_PPDSDR_H & (1UL << x))
-
-#define GPIO_I_H(x)			x//do{MCF_GPIO_PPDSDR_I   = (unsigned char) (1UL << x);}while(0)
-#define GPIO_I_L(x)			x//do{MCF_GPIO_PCLRR_I    = (unsigned char)~(1UL << x);}while(0)
-#define GPIO_I_O(x)			x//do{MCF_GPIO_PDDR_I    |= (unsigned char) (1UL << x);}while(0)
-#define GPIO_I_I(x)			x//do{MCF_GPIO_PDDR_I    &= (unsigned char)~(1UL << x);}while(0)
-#define GPIO_I_S(x)			(MCF_GPIO_PPDSDR_I & (1UL << x))
-
-#define GPIO_J_H(x)			x//do{MCF_GPIO_PPDSDR_J   = (unsigned char) (1UL << x);}while(0)
-#define GPIO_J_L(x)			x//do{MCF_GPIO_PCLRR_J    = (unsigned char)~(1UL << x);}while(0)
-#define GPIO_J_O(x)			x//do{MCF_GPIO_PDDR_J    |= (unsigned char) (1UL << x);}while(0)
-#define GPIO_J_I(x)			x//do{MCF_GPIO_PDDR_J    &= (unsigned char)~(1UL << x);}while(0)
-#define GPIO_J_S(x)			(MCF_GPIO_PPDSDR_J & (1UL << x))
-
-#define GPIO_K_H(x)			x//do{MCF_GPIO_PPDSDR_K   = (unsigned char) (1UL << x);}while(0)
-#define GPIO_K_L(x)			x//do{MCF_GPIO_PCLRR_K    = (unsigned char)~(1UL << x);}while(0)
-#define GPIO_K_O(x)			x//do{MCF_GPIO_PDDR_K    |= (unsigned char) (1UL << x);}while(0)
-#define GPIO_K_I(x)			x//do{MCF_GPIO_PDDR_K    &= (unsigned char)~(1UL << x);}while(0)
-#define GPIO_K_S(x)			(MCF_GPIO_PPDSDR_K & (1UL << x))
-
-#endif
-
-

+ 3 - 11
app_public/fuxi_public/fuxi_bsp/source/ad7616.c

@@ -463,7 +463,6 @@ int adc_isr(int mod)
 		{
 			recv_init = 1;
 			//开机时裸核还没有把遥信送上下,这里重新初始化plc_init
-			// dido_init_di();	//TODO EWen 集中式采用开入开出子板形式采集遥信
 			// plc_init();		TODO EWen
 		}
 
@@ -636,25 +635,18 @@ static void updata_adc(struct t_shmdata_adc *sample_data0, uint16_t us_adc_dot_i
  */
 int adc_isr_new(int mod)
 {
-    int cnt = 0;
-    struct t_shmdata_adc sample_data0 = {0};
     int ret0 = 0;
-    int ret1 = 0;
+    struct t_shmdata_adc sample_data0 = {0};
     static volatile uint16_t smus_sample_read_index0 = 0; /* 读取adc1索引 */
 
     ret0 = shm_packet_read_v2(SHM_ADDR_W_U_ADC_1, sizeof(sample_data0), (uint8_t *)&sample_data0, sizeof(sample_data0));
     // printf("ret0=%d, sample_idx=%d, read_index=%d, us_updata=%d, us_op=%d, us_op_bk=%d\n",
     // 	ret0, sample_data0.data.us_sample_idx, smus_sample_read_index0, sample_data0.us_updata, sample_data0.us_op, sample_data0.us_op_bk);
 
-    while (ret0 > 0)
+    if (0 < ret0)
     {
-        if (++cnt > 5)
-            break;
-
-        usleep(300);
+        return -1;
     }
-    // printf("ret1=%d, sample_idx=%d, read_index=%d, us_updata=%d, us_op=%d, us_op_bk=%d\n",
-    // 	ret1, sample_data1.data.us_sample_idx, smus_sample_read_index1, sample_data1.us_updata, sample_data1.us_op, sample_data1.us_op_bk);
 
     if (ret0 > 0 && (smus_sample_read_index0 != sample_data0.data.us_sample_idx))
     {

+ 309 - 303
app_public/fuxi_public/fuxi_bsp/source/dido.c

@@ -35,17 +35,18 @@
 
 /*------------------------------ 全局变量 -------------------------------------
  */
-struct di g_di[EQU_SLOT_NUM_MAX];
-struct _do g_do[EQU_SLOT_NUM_MAX];
-struct di_struct g_di_st[EQU_SLOT_NUM_MAX][DIDO_MAX_DI_PER_SLOT];
-struct do_struct g_do_st[DO_NUM];
+extern u32 g_brd_type_kz;
 
 u16 g_do_status; // 开出状态,因为仅主板有开出
 u32 g_do_start_time;
-
 int g_do_flag;
+u8 g_di_slot = 0;// 开入板卡配置槽位
+
+struct di g_di[EQU_SLOT_NUM_MAX];
+struct _do g_do[EQU_SLOT_NUM_MAX];
+struct di_struct g_di_st[EQU_SLOT_NUM_MAX][DIDO_MAX_DI_PER_SLOT];
+struct do_struct g_do_st[DO_NUM];
 
-extern u32 g_brd_type_kz;
 struct rt_stat g_stat_di_delay;
 struct rt_stat g_stat_do_delay;
 
@@ -54,27 +55,224 @@ static u32 error_count = 0;
 
 struct do_time g_do_time[EQU_SLOT_NUM_MAX];
 
-/*------------------------------ 函数声明 -------------------------------------
+/*------------------------------ 内部函数 -------------------------------------
+内部函数以下划线‘_’开头,不需要检查参数的合法性.
+*/
+
+/**
+ * @brief          开出状态更新
+ * @param[in/out]  {int} on 
+ * @param[in/out]  {unsigned int} i  
+ * @return         * void
+ * @retval         none
+ * 
+ * @warning        none
+ * @note           none
+ */
+static inline void _io_do_status_update(int on, unsigned int i)
+{
+    if (on)
+    {
+        g_do_status |= (1 << i);
+        g_do_st[i].us_on = ustimer_get_origin();
+    }
+    else
+    {
+        g_do_status &= ~(1 << i);
+    }
+
+    // 更新返校检查时间
+    g_do_start_time = ustimer_get_origin();
+}
+
+/**
+ * @brief          控制开出动作
+ * @param[in/out]  {type} slot 
+ * @param[in/out]  {type} v  
+ * @param[in/out]  {type} is_on 
+ * @return         * int
+ * @retval         none
+ * 
+ * @warning        none
+ * @note           none
+ */
+static int _dido_do(u32 slot, u16 v, int is_on)
+{
+    int i;
+
+    // 循环检查开出位
+    for (i = 0; i < g_board_info[slot].do_num; i++)
+    {
+        // 如果对应开出位有效,开出。
+        if (((v >> i) & 0x1))
+        {
+            dido_do_kz(is_on, equ_get_do_channel(i));
+        }
+    }
+    if (((v >> g_board_info[slot].do_num) & 0x1)) // 启动继电器
+    {
+        dido_do_kz(is_on, DO_QD_KC);
+    }
+    return 0;
+}
+
+/**
+ * @brief          开入防抖处理
+ * @param[in/out]  {type} slot 
+ * @param[in/out]  {type} di_num 
+ * @param[in/out]  {type} di 
+ * @param[in/out]  {type} ts 
+ * @return         * int
+ * @retval         none
+ * 
+ * @warning        none
+ * @note           none
  */
-static int _dido_do(u32 slot, u16 v, int is_on);
-static int _get_di(int slot, u16 di_num, u32 di, struct timespec ts);
-static inline void _io_do_status_update(int on, unsigned int i);
-unsigned int change_di_ch(unsigned int di);
+static int _get_di(int slot, u16 di_num, u32 di, struct timespec ts)
+{
+    int i, b_on;
+    struct rtc_time_t ct;
+    uint32 diff_nsec;
+
+    // 获取遥信值,并记录时间戳。
+    // 用秒的低8位和纳秒的高24位合成32位时间戳
+    //	clk_time_get(&ts);
+
+    // 循环处理每一个遥信
+    for (i = 0; i < di_num; i++)
+    {
+        struct di_struct *pt = &g_di_st[slot][i];
+
+        // 处理当前变位遥信。
+        b_on = (di & (1 << i)) ? 1 : 0;
+        if (b_on ^ pt->b_on)
+        {
+            if (!pt->b_first_change)
+            {
+                pt->b_first_change = true;
+                pt->tm_back = 0;
+                pt->tm_keep = 0;
+
+                // 记录变位的起始时刻点
+                pt->ts_di = ts;
+                pt->dt = g_adc_dots_data_count;
+#ifdef DIDO_TS_MODE
+                pt->ts_tmp = ts;
+#endif
+            }
+            else
+            {
+                // 累计保持时间
+#ifdef DIDO_TS_MODE
+                if (ts.tv_nsec >= pt->ts_tmp.tv_nsec)
+                {
+                    diff_nsec = ts.tv_nsec - pt->ts_tmp.tv_nsec;
+                }
+                else
+                {
+                    diff_nsec = 1000000000ul - pt->ts_tmp.tv_nsec + ts.tv_nsec;
+                }
+                if (diff_nsec > 312500ul)
+                {
+                    diff_nsec = 156250ul;
+                }
+                pt->acc_nsec += diff_nsec;
+                while (pt->acc_nsec >= 156250ul)
+                {
+                    pt->tm_keep++;
+                    pt->acc_nsec -= 156250ul;
+                }
+                pt->ts_tmp = ts;
+
+                //		rt_printf("diff_nsec:%d, pt->tm_keep:%d\r\n", diff_nsec, pt->tm_keep);
+#else
+                pt->tm_keep++;
+#endif
+                pt->tm_back = 0; // 现在返回门限是0.5us,所有必须在此清零。
+                // 保持时间到,处理变位
+                if (pt->tm_keep > pt->tm_filter)
+                {
+                    // 记录遥信状态
+#if defined YX_DI_ERROR // 广西遥信异常后,遥信屏蔽不保存,不上报
+                    if (g_run_stu.yxEnable == 0 && b_on == 0)
+                    {
+                        pt->type = SOE_TYPE_TST;
+                        pt->b_first_change = false;
+                        pt->tm_back = 0;
+                        pt->tm_keep = 0;
+                        return 0;
+                    }
+#endif
+                    pt->b_on = b_on;
+
+                    if (g_di[slot].inv[0] & (1 << i))
+                    {
+                        b_on = !b_on;
+                    }
+                    if (b_on)
+                    {
+                        g_di[slot].value[0] |= (1 << i);
+                    }
+                    else
+                    {
+                        g_di[slot].value[0] &= ~(1 << i);
+                    }
+
+                    // 记录SOE
+                    soe_record_yx((WORD)(i + (slot << 8)), b_on, &pt->ts_di);
+                    timespec_to_rtc(ts, &ct, 1);
+
+                    rt_printf("di=%x value[0]=%x\r\n", di, g_di[slot].value[0]);
+
+                    // 更新逻辑模型中的值
+                    sw_di_set(g_di_st[slot][i].owner, g_di_st[slot][i].type, b_on ? SW_DI_TYPE_ON : SW_DI_TYPE_OFF);
+
+                    // 更新记录
+                    g_di[slot].ts_t[i][g_di[slot].ts_i[i].n] = pt->dt;
+                    g_di[slot].ts_v[i][g_di[slot].ts_i[i].n] = b_on;
+                    g_di[slot].ts_i[i].n++;
+
+                    // 滤波处理数据复位
+                    pt->b_first_change = false;
+                    pt->tm_back = 0;
+                    pt->tm_keep = 0;
+                }
+            }
+        }
+        else if (pt->b_first_change)
+        {
+            // 变位返回处理
+            pt->tm_back++;
+            // 屏蔽下一行,
+            // 最新逻辑,有效电平不连续可计数累加;
+            // 无效电平连续超0.5ms复归,且不连续累加。
+            // pt->tm_keep=0;
+
+            // if(pt->tm_back > pt->tm_filter)
+            if (pt->tm_back > 4) // 针对高频振荡波测试优化,返回门限设置为500us附件(4*156=624us)。
+            {
+                pt->tm_back = 0;
+                pt->tm_keep = 0;
+                pt->b_first_change = false;
+            }
+        }
+    }
+
+    return 0;
+}
 
 /*------------------------------ 外部函数 -------------------------------------
 外部函数供其它实体文件引用,必须仔细检查传入参数的合法性.
 */
-/******************************************************************************
-函数名称:	dido_init
-函数版本:	01.01
-创建作者:
-创建日期:	2013-03-13
-函数说明:	开入开出初始化
-参数说明:	无
-返回值:  	无
-修改记录:
-*/
 
+/**
+ * @brief          开入数据初始化
+ * @return         * void
+ * @retval         none
+ * 
+ * @warning        none
+ * @note           none
+ */
 void dido_init_di(void)
 {
     u32 i, slot;
@@ -108,6 +306,14 @@ void dido_init_di(void)
     }
 }
 
+/**
+ * @brief          开入开出初始化
+ * @return         * int
+ * @retval         none
+ * 
+ * @warning        none
+ * @note           none
+ */
 int dido_init(void)
 {
     u32 i;
@@ -146,7 +352,16 @@ int dido_init(void)
     return 0;
 }
 
-// 只有分合闸有选择启动继电器
+/**
+ * @brief          判断是否需要动作预置继电器
+ * @param[in/out]  {u32} slot 
+ * @param[in/out]  {u32} index 
+ * @return         * int
+ * @retval         none
+ * 
+ * @warning        none
+ * @note           none
+ */
 int dido_do_have_select(u32 slot, u32 index)
 {
     int i = 0;
@@ -481,12 +696,7 @@ int dido_do_kz(int on, unsigned int i)
             _io_do_status_update(1, DO_QD_KC);
         }
     }
-    // if(i<=DO_PWM3)
-    // {
-    // 	gpio_pwm_do(on, i);		// 对应X3端子的OUT3,分闸
-    // 	_io_do_status_update(on,i);
-    // }
-    // else
+
     if (i == DO_QD_KC) // 启动继电器出口
     {
         if (!on)
@@ -515,282 +725,26 @@ int dido_do_kz(int on, unsigned int i)
     return 0;
 }
 
-/*------------------------------ 内部函数 -------------------------------------
-内部函数以下划线‘_’开头,不需要检查参数的合法性.
-*/
-static inline void _io_do_status_update(int on, unsigned int i)
-{
-    if (on)
-    {
-        g_do_status |= (1 << i);
-        g_do_st[i].us_on = ustimer_get_origin();
-    }
-    else
-    {
-        g_do_status &= ~(1 << i);
-    }
-
-    // 更新返校检查时间
-    g_do_start_time = ustimer_get_origin();
-}
-
-static int _dido_do(u32 slot, u16 v, int is_on)
-{
-    int i;
-
-    // 循环检查开出位
-    for (i = 0; i < g_board_info[slot].do_num; i++)
-    {
-        // 如果对应开出位有效,开出。
-        if (((v >> i) & 0x1))
-        {
-            dido_do_kz(is_on, equ_get_do_channel(i));
-        }
-    }
-    if (((v >> g_board_info[slot].do_num) & 0x1)) // 启动继电器
-    {
-        dido_do_kz(is_on, DO_QD_KC);
-    }
-    return 0;
-}
-
-/******************************************************************************
-函数名称:	_get_di
-函数版本:	01.01
-创建作者:
-创建日期:	2013-03-13
-函数说明:	开入防抖处理
-参数说明:	无
-返回值:
-修改记录:
-*/
-#ifdef CN_AREA_GUANGXI // 遥信全部为0
-u32 kktime_0 = 0;
-#endif
-static int _get_di(int slot, u16 di_num, u32 di, struct timespec ts)
-{
-    int i, b_on;
-    struct rtc_time_t ct;
-    uint32 diff_nsec;
-
-//	struct timespec ts;
-#if 0 // #ifdef CN_AREA_GUANGXI//遥信全部为0,则关闭屏幕或者关机
-	if(di==0)
-	{
-		kktime_0++;
-		if(kktime_0 > 10)
-		{
-#if 1
-			g_run_stu.yxError=true;	//遥信错误,关闭屏幕
-#else
-			char *argv[] = {"poweroff", NULL};
-			char *envp[] = { NULL };
-			call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);//关机
-#endif
-			return 0;
-		}
-	}
-	else
-	{
-		g_run_stu.yxError=0;
-		kktime_0=0;
-	}
-#endif
-
-    // 获取遥信值,并记录时间戳。
-    // 用秒的低8位和纳秒的高24位合成32位时间戳
-    //	clk_time_get(&ts);
-
-    // 循环处理每一个遥信
-    for (i = 0; i < di_num; i++)
-    {
-        struct di_struct *pt = &g_di_st[slot][i];
-
-        // 处理当前变位遥信。
-        b_on = (di & (1 << i)) ? 1 : 0;
-        if (b_on ^ pt->b_on)
-        {
-            if (!pt->b_first_change)
-            {
-                pt->b_first_change = true;
-                pt->tm_back = 0;
-                pt->tm_keep = 0;
-
-                // 记录变位的起始时刻点
-                pt->ts_di = ts;
-                pt->dt = g_adc_dots_data_count;
-#ifdef DIDO_TS_MODE
-                pt->ts_tmp = ts;
-#endif
-            }
-            else
-            {
-                // 累计保持时间
-#ifdef DIDO_TS_MODE
-                if (ts.tv_nsec >= pt->ts_tmp.tv_nsec)
-                {
-                    diff_nsec = ts.tv_nsec - pt->ts_tmp.tv_nsec;
-                }
-                else
-                {
-                    diff_nsec = 1000000000ul - pt->ts_tmp.tv_nsec + ts.tv_nsec;
-                }
-                if (diff_nsec > 312500ul)
-                {
-                    diff_nsec = 156250ul;
-                }
-                pt->acc_nsec += diff_nsec;
-                while (pt->acc_nsec >= 156250ul)
-                {
-                    pt->tm_keep++;
-                    pt->acc_nsec -= 156250ul;
-                }
-                pt->ts_tmp = ts;
-
-                //		rt_printf("diff_nsec:%d, pt->tm_keep:%d\r\n", diff_nsec, pt->tm_keep);
-#else
-                pt->tm_keep++;
-#endif
-                pt->tm_back = 0; // 现在返回门限是0.5us,所有必须在此清零。
-                // 保持时间到,处理变位
-                if (pt->tm_keep > pt->tm_filter)
-                {
-                    // 记录遥信状态
-#if defined CN_AREA_GUANGXI || defined YX_DI_ERROR // 广西遥信异常后,遥信屏蔽不保存,不上报
-                    if (g_run_stu.yxEnable == 0 && b_on == 0)
-                    {
-                        pt->type = SOE_TYPE_TST;
-                        pt->b_first_change = false;
-                        pt->tm_back = 0;
-                        pt->tm_keep = 0;
-                        return 0;
-                    }
-#endif
-                    pt->b_on = b_on;
-
-                    if (g_di[slot].inv[0] & (1 << i))
-                    {
-                        b_on = !b_on;
-                    }
-                    if (b_on)
-                    {
-                        g_di[slot].value[0] |= (1 << i);
-                    }
-                    else
-                    {
-                        g_di[slot].value[0] &= ~(1 << i);
-                    }
-
-                    // 记录SOE
-                    soe_record_yx((WORD)(i + (slot << 8)), b_on, &pt->ts_di);
-                    timespec_to_rtc(ts, &ct, 1);
-
-                    rt_printf("di=%x value[0]=%x\r\n", di, g_di[slot].value[0]);
-
-                    // 更新逻辑模型中的值
-                    sw_di_set(g_di_st[slot][i].owner, g_di_st[slot][i].type, b_on ? SW_DI_TYPE_ON : SW_DI_TYPE_OFF);
-
-                    // 更新记录
-                    g_di[slot].ts_t[i][g_di[slot].ts_i[i].n] = pt->dt;
-                    g_di[slot].ts_v[i][g_di[slot].ts_i[i].n] = b_on;
-                    g_di[slot].ts_i[i].n++;
-
-                    // 滤波处理数据复位
-                    pt->b_first_change = false;
-                    pt->tm_back = 0;
-                    pt->tm_keep = 0;
-                }
-            }
-        }
-        else if (pt->b_first_change)
-        {
-            // 变位返回处理
-            pt->tm_back++;
-            // 屏蔽下一行,
-            // 最新逻辑,有效电平不连续可计数累加;
-            // 无效电平连续超0.5ms复归,且不连续累加。
-            // pt->tm_keep=0;
-
-            //			if(pt->tm_back > pt->tm_filter)
-            if (pt->tm_back > 4) // 针对高频振荡波测试优化,返回门限设置为500us附件(4*156=624us)。
-            {
-                pt->tm_back = 0;
-                pt->tm_keep = 0;
-                pt->b_first_change = false;
-            }
-        }
-    }
-
-    return 0;
-}
-
-#if (0) /* TODO 获取开入量 */
+#if !defined CPU_FUXI
+/**
+ * @brief          开入量更新
+ * @param[in/out]  {uint32_t} _value_new 值
+ * @param[in/out]  {uint8_t} _index 下标
+ * @param[in/out]  {struct timespec *ts} ts 时间
+ * @return         * int
+ * @retval         none
+ * 
+ * @warning        none
+ * @note           none
+ */
 int dido_di_update(uint32_t _value_new, uint8_t _index, struct timespec *ts)
 {
-    static uint8_t init_flag = 0;
-    uint32_t dt;
-    int i, j, is_on;
-
-    if (init_flag == 0)
-    {
-        init_flag = 1;
-
-        // DI数量未超32个,只用第一个元素就够了
-        g_di[g_di_slot].value[0] = _value_new;
-
-        // 更新逻辑模型中的值
-        for (i = 0; i < DIDO_MAX_DI_PER_SLOT; i++)
-        {
-            is_on = (g_di[g_di_slot].value[0] & (1 << i)) ? 1 : 0;
-            sw_di_set(g_di_st[g_di_slot][i].owner,
-                      g_di_st[g_di_slot][i].type,
-                      is_on ? SW_DI_TYPE_ON : SW_DI_TYPE_OFF);
-
-            // 双点的值也需要重新初始化
-            plc_db_init_value(g_di_slot, i, is_on);
-
-            // 遥信时标
-            g_di[g_di_slot].ts_t[i][g_di[g_di_slot].ts_i[i].n] = 0;
-            g_di[g_di_slot].ts_v[i][g_di[g_di_slot].ts_i[i].n] = is_on;
-            g_di[g_di_slot].ts_i[i].n++;
-        }
 
-        g_di[g_di_slot].bInited = RT_TRUE;
-
-        return 0;
-    }
-
-    if (_value_new == 1)
-        g_di[g_di_slot].value[0] |= _value_new << _index;
-    else
-        g_di[g_di_slot].value[0] &= ~((_value_new ^ 1) << _index);
-
-    // clock_gettime(CLOCK_REALTIME, &ts);
-
-    // 记录遥信变位
-    is_on = (g_di[g_di_slot].value[0] & (1 << _index)) ? 1 : 0;
-    soe_record_yx(_index + (g_di_slot << 8), is_on, ts);
-
-    // 更新逻辑模型中的值
-    sw_di_set(g_di_st[g_di_slot][_index].owner,
-              g_di_st[g_di_slot][_index].type,
-              (is_on) ? SW_DI_TYPE_ON : SW_DI_TYPE_OFF);
-
-    // 更新记录
-    // TODO:原DTU此处更新采样点会关中断更新,但考虑到频繁关中断会影响采样,此处不关中断先观察
-    dt = g_adc_dots_count;
-    g_di[g_di_slot].ts_t[_index][g_di[g_di_slot].ts_i[_index].n] = dt;
-    g_di[g_di_slot].ts_v[_index][g_di[g_di_slot].ts_i[_index].n] = is_on;
-    g_di[g_di_slot].ts_i[_index].n++;
-
-    // rt_kprintf("板卡:%d,di[%d]:%d\r\n",g_di_slot,_index,is_on); //test_use
 }
+#endif
 
 /**
  * @brief          Get the shm didata object
- * @author         lch (lch_work@foxmail.com)
- * @version        1.0
- * @date           20251219
  * @return         * int
  * @retval         none
  *
@@ -800,20 +754,72 @@ int dido_di_update(uint32_t _value_new, uint8_t _index, struct timespec *ts)
 int get_shm_didata(void)
 {
     int l_read_ret = 0, l_cnt = 0;
+    u32 ul_di_state = 0, dt;
     struct t_shmdata_di shm_data_di = {0};
+    static struct t_sd_di_status smt_di[DI_MAX] = {0}, smt_di_bk[DI_MAX] = {0}; /* 数据 */
+    struct timespec ts;
 
     l_read_ret = shm_packet_read_v2(SHM_ADDR_W_DI, sizeof(shm_data_di), (uint8_t *)&shm_data_di, sizeof(shm_data_di));
 
-    while (l_read_ret > 0)
+    if (l_read_ret < 0)
+    {
+        return -1;
+    }
+
+    if (l_read_ret > 0)
     {
-        if (++l_cnt > 5)
-            break;
+        memcpy((void *)&smt_di, (void *)&shm_data_di.di, sizeof(struct t_sd_di_status) * DI_MAX);
+
+        if (false == g_di[g_di_slot].bInited)
+        {
+            for (uint8_t i = 0; i < DI_MAX; i++)
+            {
+                ul_di_state |= smt_di[i].uc_state << i;
+                sw_di_set(g_di_st[g_di_slot][i].owner,
+                          g_di_st[g_di_slot][i].type,
+                          smt_di[i].uc_state ? SW_DI_TYPE_ON : SW_DI_TYPE_OFF);
+                // 双点的值也需要重新初始化
+                plc_db_init_value(g_di_slot, i, smt_di[i].uc_state);
+                // 遥信时标
+                g_di[g_di_slot].ts_t[i][g_di[g_di_slot].ts_i[i].n] = 0;
+                g_di[g_di_slot].ts_v[i][g_di[g_di_slot].ts_i[i].n] = smt_di[i].uc_state;
+                g_di[g_di_slot].ts_i[i].n++;
+
+                memcpy((void *)&smt_di_bk, (void *)&shm_data_di.di, sizeof(struct t_sd_di_status) * DI_MAX);
+            }
+            g_di[g_di_slot].bInited = TRUE;
+        }
+
+        for (uint8_t i = 0; i < DI_MAX; i++)
+        {
+            ul_di_state |= smt_di[i].uc_state << i;
 
-        usleep(300);
+            if (smt_di_bk[i].uc_state != smt_di[i].uc_state)
+            {
+                transform_msts_to_tts(smt_di[i].ull_timestamp, &ts);
+                soe_record_yx(i + (g_di_slot << 8), smt_di[i].uc_state, &ts);
+
+                // 更新逻辑模型中的值
+                sw_di_set(g_di_st[g_di_slot][i].owner,
+                          g_di_st[g_di_slot][i].type,
+                          (smt_di[i].uc_state) ? SW_DI_TYPE_ON : SW_DI_TYPE_OFF);
+
+                // 更新记录
+                dt = g_adc_dots_count;
+                g_di[g_di_slot].ts_t[i][g_di[g_di_slot].ts_i[i].n] = dt;
+                g_di[g_di_slot].ts_v[i][g_di[g_di_slot].ts_i[i].n] = smt_di[i].uc_state;
+                g_di[g_di_slot].ts_i[i].n++;
+                smt_di_bk[i].uc_state = smt_di[i].uc_state;
+                // dp_err_n_c_rt("change smt_di[%02d].uc_state = %d", i, smt_di[i].uc_state);
+            }
+        }
+        g_di[g_di_slot].value[0] = ul_di_state;
+        // dp_err_n_c_rt("g_di[%02d].value[0] = 0x%04x", g_di_slot, g_di[g_di_slot].value[0]);
+        rt_printf("\r\n");
     }
-}
-#endif
 
+    return l_read_ret;
+}
 
 /*------------------------------ 测试函数 -------------------------------------
 一个实体文件必须带一个本模块的测试函数来进行单元测试,如果的确不方便在本模块中

+ 135 - 197
app_public/fuxi_public/fuxi_bsp/source/equ_fuxi.c

@@ -35,43 +35,38 @@ struct board_info_frame
 // 控制板类型
 u32 g_brd_type_kz; 
 
+// 采样板索引和插槽的对应关系
+const int g_ac_index_to_slot[EQU_SLOT_AC_NUM] = {1};
+
+// 采样板起始槽位,每种机箱不一样。
+u32 g_ac_slot_begin;  
+
+// 记录频率对应ui通道的索引值
+int g_ui_freq[CFG_FREQ_NUM];	
+
 // 模拟量对应关系
 static const s8 g_ac_index[BOARD_TYPE_KZ_NUM][EQU_SLOT_AC_CHN] = 
 {
     {0X01, 0X03, 0X05, 0X07, 0XFF, 0XFF, 0XFF, 0XFF, 0X00, 0X02, 0X04, 0X06, 0X0E, 0X0C, 0X0A, 0X08}, // 24款分布式 lch
-	{0X01,0X03,0X05,0X07,0X09,0X0B,0X0D,0X04,0X0A,0X0E,0X02,0X08,0X0C,0X00,0X06,0X0F},	// KC00
-	{0X01,0X03,0X05,0X07,0X09,0X0B,0X0D,0X0F,0x0E,0x04,0x02,0x08,0x0C,0x00,0x06,0x0A},	// KC08
-	{0X0C,0X0E,0X01,0X03,0X00,0X02,0X04,0X06,0X08,0X0A,0X05,0X07,0X09,0X0B,0X0D,0X0F},	// KC10,10AC
-	{0X01,0X03,0X05,0X07,0X09,0X0B,0X0D,0X04,0X0A,0X0E,0X02,0X08,0X0C,0X00,0X06,0X0F},	// 一体式分布式DTU控制板
-	{0X01,0X03,0X05,0X07,0X09,0X0B,0X0D,0X0F,0x0E,0x04,0x02,0x08,0x0C,0x00,0x06,0x0A},	// 后拔插分布式DTU控制板 FB_V3_22_12
-	{0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00},	//  18  老版本分布式主板类型,不起作用
-	{0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00},	//	19	老版本分布式主板类型,不起作用
-	{0X01,0X03,0X05,0X07,0X09,0X0B,0X0D,0X0F,0x0E,0x04,0x02,0x08,0x0C,0x00,0x06,0x0A},	// 类型 20 FB_V4_24_12
-	{0X01,0X03,0X05,0X07,0X09,0X0B,0X0D,0X0F,0x08,0x0A,0x0C,0x0E,0x06,0x04,0x02,0x00},	//类型 21 FB_V4.1_24_12
-	{0X01,0X03,0X05,0X07,0X09,0X0B,0X0D,0X0F,0x08,0x0A,0x0C,0x0E,0x06,0x04,0x02,0x00},	//类型 22 FB_V3.1_22_12
-	{0X01,0X03,0X05,0X07,0X09,0X0B,0X0D,0X0F,0x0E,0x04,0x02,0x08,0x0C,0x00,0x06,0x0A},	//类型 23 FB_V3D_1_22_12
-	{0X01,0X03,0X05,0X07,0X09,0X0B,0X0D,0X0F,0x0E,0x04,0x02,0x08,0x0C,0x00,0x06,0x0A},	//类型 24 V4_D_30_12
 };
+
 //遥信转换表
-s8 g_change_di_index[BOARD_TYPE_KZ_NUM][EQU_DB_YX_NUM] = 
+s8 g_change_di_index[BOARD_TYPE_KZ_NUM][EQU_DB_YX_NUM] =
 {
-	{ 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32},//13
-	{ 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32},//14 FB_V3_22_8 21,20,19,22,23,24,25,26,27,28,29,30,31,32}
-	{ 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32},//15
-	{ 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,00,00,00,00,00,00,00,00,00,00,00,00,00},//16 FBV1_19_6
-	{ 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32},//17 FB_V3_22_12
-	{ 1, 2, 3, 5, 7, 9,11,13,15,19,21,23,24,18,17, 4, 6, 8,10,12,14,16,20,22,00,00,00,00,00,00,00,00},//18 null
-	{ 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32},//19 null
-	{ 1, 2, 3, 5, 7, 9,11,13,15,19,21,23,24,18,17, 4, 6, 8,10,12,14,16,20,22,00,00,00,00,00,00,00,00},//20 FB_V4_24_12
-  	{ 1, 2, 3, 5, 7, 9,11,13,15,19,21,23,24,18,17, 4, 6, 8,10,12,14,16,20,22,00,00,00,00,00,00,00,00},//21 FB_V4.1_24_12
-  	{ 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,24,23,21,22,25,26,27,28,29,30,31,32},//22 FB_V3.1_22_12
-	{ 2, 4, 6, 8,10,12,14,15,16, 1, 3, 5, 7, 9,11,13,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32},//23 FB_V3D_122_12
-	{ 1, 3, 5, 7, 9,11,13,15,19,21,25,27,29, 2, 4, 6, 8,10,12,14,16,20,22,26,28,30,17,18,23,24,00,00},//24 V4_D_30_12
-
+    {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}, // 13
+    {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}, // 14 FB_V3_22_8 21,20,19,22,23,24,25,26,27,28,29,30,31,32}
+    {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}, // 15
+    {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00}, // 16 FBV1_19_6
+    {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}, // 17 FB_V3_22_12
+    {1, 2, 3, 5, 7, 9, 11, 13, 15, 19, 21, 23, 24, 18, 17, 4, 6, 8, 10, 12, 14, 16, 20, 22, 00, 00, 00, 00, 00, 00, 00, 00}, // 18 null
+    {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}, // 19 null
+    {1, 2, 3, 5, 7, 9, 11, 13, 15, 19, 21, 23, 24, 18, 17, 4, 6, 8, 10, 12, 14, 16, 20, 22, 00, 00, 00, 00, 00, 00, 00, 00}, // 20 FB_V4_24_12
+    {1, 2, 3, 5, 7, 9, 11, 13, 15, 19, 21, 23, 24, 18, 17, 4, 6, 8, 10, 12, 14, 16, 20, 22, 00, 00, 00, 00, 00, 00, 00, 00}, // 21 FB_V4.1_24_12
+    {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 24, 23, 21, 22, 25, 26, 27, 28, 29, 30, 31, 32}, // 22 FB_V3.1_22_12
+    {2, 4, 6, 8, 10, 12, 14, 15, 16, 1, 3, 5, 7, 9, 11, 13, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}, // 23 FB_V3D_122_12
+    {1, 3, 5, 7, 9, 11, 13, 15, 19, 21, 25, 27, 29, 2, 4, 6, 8, 10, 12, 14, 16, 20, 22, 26, 28, 30, 17, 18, 23, 24, 00, 00}, // 24 V4_D_30_12
 };
 
-
-
 // 开出对应关系
 static const s8 g_do_index[BOARD_TYPE_KZ_NUM][DO_NUM] = 
 {
@@ -81,127 +76,46 @@ static const s8 g_do_index[BOARD_TYPE_KZ_NUM][DO_NUM] =
 	{DO_OUT9,DO_OUT0,DO_OUT2,DO_OUT4,DO_OUT6,DO_OUT1,DO_OUT3,DO_OUT5,DO_OUT7,-1}, 	//15
 	{-1,-1,-1,-1-1,-1,-1,-1-1,-1,-1,-1},  //  18  老版本分布式主板类型,不起作用
 	{-1,-1,-1,-1-1,-1,-1,-1-1,-1,-1,-1},  //  19  老版本分布式主板类型,不起作用
-	
-	// {DO_PWM2,DO_PWM1,DO_OUT7,DO_OUT6,DO_OUT3,DO_OUT2,DO_PWM0,DO_PWM3,DO_OUT0,DO_OUT1,DO_OUT5,-1}, //20  V4 类型20
-	// {DO_PWM2,DO_PWM1,DO_OUT7,DO_OUT6,DO_OUT3,DO_OUT2,DO_PWM0,DO_PWM3,DO_OUT0,DO_OUT1,DO_OUT5,-1}, //21  V4.1 类型20
-	// {DO_PWM0,DO_PWM3,DO_OUT0,DO_OUT1,DO_OUT6,DO_OUT5,DO_OUT2,DO_OUT3,DO_OUT4,DO_OUT7,DO_PWM1,-1},	//22 FB_V3.1_22_12
-	// {DO_PWM0,DO_PWM3,DO_OUT0,DO_OUT1,DO_OUT6,DO_OUT5,DO_OUT2,DO_OUT3,DO_OUT4,DO_OUT7,DO_PWM1,-1},	//23 FB_V3D1_22_12
-	// {DO_OUT2,DO_OUT3,DO_PWM2,DO_PWM0,DO_PWM3,DO_OUT0,DO_OUT1,DO_OUT6,DO_OUT5,DO_OUT7,DO_PWM1,-1},//24 V4_D_30_12
-
 };
 
 
-// 采样板索引和插槽的对应关系
-const int g_ac_index_to_slot[EQU_SLOT_AC_NUM] = {1};
-
-// 采样板起始槽位,每种机箱不一样。
-u32 g_ac_slot_begin;  
-
-// 记录频率对应ui通道的索引值
-int g_ui_freq[CFG_FREQ_NUM];	
-
-
-
-
-
 /*------------------------------ 函数声明 -------------------------------------
 */
-int equ_slot_config_di(int slot);
-int equ_slot_config_do(int slot);
-unsigned int chDi;
 unsigned int change_di_ch(unsigned int di)
 {
-	register int i,rts=0;
-	#if 0
+    register int i, rts = 0;
+#if 0
 	static int di_bak;
 	if(di_bak!=di)
 	{
 		rt_printf_time("change_di_ch di=%x \r\n",di);
 		di_bak=di;
 	}
-	#endif
-	for(i=0;i<EQU_DB_YX_NUM;i++)
-	{
-		if(g_change_di_index[g_brd_type_kz][i]!=0 && g_change_di_index[g_brd_type_kz][i]<=EQU_DB_YX_NUM)
-		{
-			if(di>>(g_change_di_index[g_brd_type_kz][i]-1)&0x01)		
-				rts|= (1<<i);
-		}
-	}
-	//rt_printf("%d %d  。。",rts,g_brd_type_kz);
-	return rts;
+#endif
+    for (i = 0; i < EQU_DB_YX_NUM; i++)
+    {
+        if (g_change_di_index[g_brd_type_kz][i] != 0 && g_change_di_index[g_brd_type_kz][i] <= EQU_DB_YX_NUM)
+        {
+            if (di >> (g_change_di_index[g_brd_type_kz][i] - 1) & 0x01)
+                rts |= (1 << i);
+        }
+    }
+    // rt_printf("%d %d  。。",rts,g_brd_type_kz);
+    return rts;
 }
 
 /*------------------------------ 外部函数 -------------------------------------
 外部函数供其它实体文件引用,必须仔细检查传入参数的合法性.
 */
-int equ_config_di(void)
-{
-	u32 i;
-	struct equ_config_di *ecd;
-
-	
-
-	memset(&g_di_st,0,sizeof(g_di_st));
-
-	// 用户配置的保持时间、拥有者、类型
-	ecd = g_equ_config_di;
-	for(i=0;i<g_equ_config->di_num;i++)
-	{
-		
-		// 开入扫描在156us中断,通过以下算法,得出对应不同防抖延时的最佳动态转换系数,理论误差为156us左右
-
-		//g_di_st[ecd->slot][ecd->index].tm_filter = ecd->filter_time * 1000 / 156;
-
-		if(ecd->filter_time>=10000)
-		{
-			g_di_st[ecd->slot][ecd->index].tm_filter = ecd->filter_time * 3200 / 500;
-			
-			g_di_st[ecd->slot][ecd->index].tm_filter -= (g_di_st[ecd->slot][ecd->index].tm_filter/10000);
-		}
-		else
-		{
-			g_di_st[ecd->slot][ecd->index].tm_filter = ecd->filter_time * 3200 / 500;
-		}
-
-	
-		//rt_printf("filter_time[%d]=%d\r\n",i,ecd->filter_time);
-
-		
-		g_di_st[ecd->slot][ecd->index].owner = ecd->owner;
-		g_di_st[ecd->slot][ecd->index].type = ecd->type;
-
-		ecd++;
-	}
-
-	return 0;
-}
-
-
-int equ_config_do(void)
-{
-	u32 i,index;
-	struct equ_config_do *ecd;
-
-	memset(&g_do_st,0,sizeof(struct do_struct)*14);	
-
-	// 用户配置的保持时间
-	ecd = g_equ_config_do;
-	for(i=0;i<g_equ_config->do_num;i++)
-	{
-		if(ecd->slot == EQU_SLOT_KZ)
-		{
-			index = equ_get_do_channel(ecd->index);
-			g_do_st[index].us_keep = (u32)ecd->time_pulse;
-			g_do_st[index].us_keep *= 1000;		//ms转换为us
-		}
-		ecd++;
-	}
-
-	return 0;
-}
-
 
+/**
+ * @brief          远动参数投入之后 遥信防抖时间的更新
+ * @return         * int
+ * @retval         none
+ * 
+ * @warning        none
+ * @note           none
+ */
 int equ_config_di_yd(void)
 {
 	u32 i;
@@ -257,60 +171,74 @@ int equ_config_do_yd(void)
 	return 0;
 }
 
-int equ_init_later(void)
+int equ_init_di(void)
 {
 	int i,ui;
 	struct equ_config_di *ecd;
 
-	// 采样板起始槽位
-	g_ac_slot_begin = EQU_SLOT_AC_BEGIN;
-
-	// 检查频率硬件通道对应的UI。
-	g_ui_freq[0] = UI_NUM;
-	g_ui_freq[1] = UI_NUM;
-	for(i=0; i< g_equ_config->ac_num; i++)
-	{
-		// 频率通道必须是配置了的公共电压类型
-		if(g_equ_config_ac[i].type == 0 || g_equ_config_ac[i].owner != 0)
-		{
-			continue;
-		}
-
-		ui = g_equ_config_ac[i].type -1;
-		if(ui >= PUB_AC_NUM)
-		{
-			continue;
-		}
-		
-		// 确定频率对应电压通道
-		if(ui < PUB_AC_NUM)
-		{
-			if(g_equ_config_ac[i].slot == 9 && g_equ_config_ac[i].index == 0)
-			{
-				g_ui_freq[0] = ui;
-			}	
-
-			if(g_equ_config_ac[i].slot == 10 && g_equ_config_ac[i].index == 0)
-			{
-				g_ui_freq[1] = ui;
-			}
-		}
-	}
-
-	// 初始化开入g_di_st结构
-	memset((unsigned char*)g_di_st,0,sizeof(g_di_st));
-	
-	ecd = g_equ_config_di;
-	for(i=0;i<g_equ_config->di_num;i++)
-	{
-		g_di_st[ecd->slot][ecd->index].tm_filter = ecd->filter_time;
-		g_di_st[ecd->slot][ecd->index].owner = ecd->owner;
-		g_di_st[ecd->slot][ecd->index].type = ecd->type;
-		ecd++;
-	}
+    // 采样板起始槽位
+    g_ac_slot_begin = EQU_SLOT_AC_BEGIN;
+
+#if !defined CPU_FUXI /* 注意t536版fuxi不使用这个配置 */
+    // 检查频率硬件通道对应的UI。
+    g_ui_freq[0] = UI_NUM;
+    g_ui_freq[1] = UI_NUM;
+    for (i = 0; i < g_equ_config->ac_num; i++)
+    {
+        // 频率通道必须是配置了的公共电压类型
+        if (g_equ_config_ac[i].type == 0 || g_equ_config_ac[i].owner != 0)
+        {
+            continue;
+        }
+
+        ui = g_equ_config_ac[i].type - 1;
+        if (ui >= PUB_AC_NUM)
+        {
+            continue;
+        }
+
+        // 确定频率对应电压通道
+        if (ui < PUB_AC_NUM)
+        {
+            if (g_equ_config_ac[i].slot == 9 && g_equ_config_ac[i].index == 0)
+            {
+                g_ui_freq[0] = ui;
+            }
+
+            if (g_equ_config_ac[i].slot == 10 && g_equ_config_ac[i].index == 0)
+            {
+                g_ui_freq[1] = ui;
+            }
+        }
+    }
+#endif
 
-	return 0;
+    // 初始化开入g_di_st结构
+    memset((unsigned char *)g_di_st, 0, sizeof(g_di_st));
+
+    ecd = g_equ_config_di;
+    for (i = 0; i < g_equ_config->di_num; i++)
+    {
+        g_di_st[ecd->slot][ecd->index].tm_filter = ecd->filter_time;
+        g_di_st[ecd->slot][ecd->index].owner = ecd->owner;
+        g_di_st[ecd->slot][ecd->index].type = ecd->type;
+        ecd++;
+    }
+
+    // 找到配置为开入板的板卡号
+    for (i = 0; i < g_equ_config->equ_slot_num; i++)
+    {
+        if (g_board_info[i].type == BOARD_TYPE_FUXI_DI)
+        {
+            g_di_slot = i;
+            break;
+        }
+    }
+	// rt_printf("g_di_slot = %d\r\n", g_di_slot);
+    return 0;
 }
+
+#ifdef BSP_CAN_ENABLE
 /******************************************************************************
 函数名称:	equ_board_info_update
 函数版本:	01.01
@@ -373,8 +301,8 @@ int equ_board_info_update(int can_bus,u8 * frame)
 	bi->can_bus = can_bus;
 
 	return 0;
-
 }
+#endif
 
 /******************************************************************************
 函数名称:	equ_ac_channel_is_ok
@@ -390,14 +318,13 @@ int equ_board_info_update(int can_bus,u8 * frame)
 */
 int equ_ac_channel_is_ok(u32 index)
 {
-	
 	// 检查参数
 	if(index >= CFG_ADC_CHANNEL)
 	{
 		return 0;
 	}
 
-	// 板卡不能插拔,直接返回ok
+	//  直接返回ok 板卡没有配置检测io
 	return 1;
 //	return g_ac_slot_is_ok[index/EQU_SLOT_AC_CHN];
 }
@@ -480,10 +407,8 @@ int equ_ac_index_to_slot(int ac_index)
 	return g_ac_index_to_slot[ac_index];
 }
 
-
-
 /******************************************************************************
-函数名称:	equ_slot_config_do
+函数名称:	equ_get_do_channel
 函数版本:	01.01
 创建作者:	   sunxi
 创建日期:	2013-08-08
@@ -500,20 +425,33 @@ int equ_get_do_channel(u32 index)
 	return g_do_index[g_brd_type_kz][index];
 }
 
-/******************************************************************************
-函数名称:	equ_slot_config_di
-函数版本:	01.01
-创建作者:	xxxxxx
-创建日期:	2014-04-08
-函数说明:	配置子板上的开入资源
-参数说明:
-	slot	插槽索引号
-返回值:	插槽号
-	0:		成功
-	其它:	失败
-修改记录:	
-*/
+/**
+ * @brief          初始化rv核数据
+ * @author         lch (lch_work@foxmail.com)
+ * @version        1.0
+ * @date           20251222
+ * @return         * int
+ * @retval         none
+ * 
+ * @warning        none
+ * @note           none
+ */
+int equ_init_rv_di(void)
+{
+#ifdef CPU_FUXI
+	struct t_shmdata_di_astime t_di_cfg = {0};
+	struct equ_config_di *ecd;
 
+    ecd = g_equ_config_di;
+    rt_printf("g_equ_config->di_num = %d\r\n", g_equ_config->di_num);
+    for (int i = 0; i < g_equ_config->di_num; i++)
+    {
+        t_di_cfg.us_as_time[i] = ecd->filter_time;
+        ecd++;
+    }
+	return shm_packet_write_v2(SHM_ADDR_R_DI_ASTIME, (uint8_t *)&t_di_cfg, sizeof(struct t_shmdata_di_astime));
+#endif
+}
 
 
 

File diff suppressed because it is too large
+ 283 - 456
app_public/fuxi_public/fuxi_bsp/source/gpio.c


+ 1 - 7
app_public/fuxi_public/fuxi_bsp/source/led_ftu.c

@@ -46,14 +46,8 @@ static int _led_kc_op(int i);
 // 通讯灯
 static int _led_comm(void)
 {
-#ifdef CN_AREA_GUANGXI
-	if(FUN_YX_SEND_YB)	//检修压板投入,通信灯常亮
-		led_set_pub(PUB_LED_COMM, LED_ON);
-#else
 	if(g_run_stu.bjx)	//检修压板投入,通信灯常亮
-		led_set_pub(PUB_LED_COMM, LED_ON);
-#endif
-		
+		led_set_pub(PUB_LED_COMM, LED_ON);	
 			
 	switch(g_led_stu[0][PUB_LED_COMM])
 	{

+ 9 - 2
app_public/fuxi_public/fuxi_bsp/source/shmem.c

@@ -117,7 +117,7 @@ int shm_packet_write_v2(uint32_t _ul_addr, uint8_t *_puc_data, uint32_t _ul_len)
 	memcpy(&mlinux_shm_base_w[_ul_addr + _ul_len - 2], &us_crc, 2);
 	// printf("cal us_crc = %04x\n", us_crc);
 
-#if (1)
+#if (0)
 	// for (int i = 0; i < _ul_len + 6; i++)
 	// {
 	//     printf("data[%d]=%04x, ", i, *(_puc_data + i+ 6));
@@ -227,7 +227,14 @@ int shm_packet_read_v2(uint32_t _ul_addr, uint32_t _ul_len, uint8_t *_puc_data_o
 		/* 在拷贝过程中,数据没有被修改 */
 		us_crc = crc16(_puc_data_out + 6, _ul_len - 8);
 		read_crc = _puc_data_out[_ul_len - 2] + ((uint16_t)_puc_data_out[_ul_len - 1] << 8);
-		// printf("cal us_crc = %04x, read us_crc = %04x\n", us_crc, read_crc);
+#if (0)
+        if (SHM_ADDR_W_DI == _ul_addr)
+        {
+            printf("us_updata = %d, ", us_updata);
+            printf("_ul_addr = 0x%x, ", _ul_addr);
+            printf("cal us_crc = %04x, read us_crc = %04x\n", us_crc, read_crc);
+        }
+#endif
 		if (us_crc != read_crc)
 		{
 			return -2;

+ 1 - 1
app_public/fuxi_public/fuxi_bsp/source/watchdog.c

@@ -188,7 +188,7 @@ static int add_item(const char *name, uint32_t *id, uint32_t period)
 			ap_watchdog.items[i].period = period;
             *id = i;
             ap_watchdog.items[i].name = name;
-			rt_printf("WDT add_item i=%d,name= %s \r\n",i, ap_watchdog.items[i].name);
+			rt_printf("WDT add_item i = %d,name = %s \r\n", i, ap_watchdog.items[i].name);
             ret = 0;
             break;
         }

+ 0 - 3
dtu/dtu_main_t536/app/app.c

@@ -30,7 +30,6 @@ struct init_t_1 g_app_init_func[]=
 	{Get_Code_CRC,"Get_Code_CRC",ERR_CODE_CRC_FLASH},
 	{tbl_create_rsc,"tbl_create_rsc",ERR_CODE_RESOURCE_TABLE},
 	{equ_init,"equ_init",ERR_CODE_EQU},
-	{equ_init_later,"equ_init_later",ERR_CODE_EQU},
 #ifdef CPU_FUXI	
 	// {adc_init,"adc_init",ERR_CODE_INIT_SOFTWARE},
 	{pit_init,"pit_init",ERR_CODE_UNKOWN},			//初始化PIT(可编程中断定时器)
@@ -38,9 +37,7 @@ struct init_t_1 g_app_init_func[]=
 	{factor_init,"factor_init",ERR_CODE_FACTOR},
 	{dcfactor_init,"dcfactor_init",ERR_CODE_DCFACTOR},
 	{sw_init,"sw_init",ERR_CODE_INIT_SWITCH},
-#ifndef CPU_FUXI	
 	{dido_init,"dido_init",ERR_CODE_INIT_SOFTWARE},
-#endif
 	{hf_init,"hf_init", ERR_CODE_INIT_SOFTWARE},
 	{rcd_init,"rcd_init",ERR_CODE_INIT_RECORD},
 	{set_create_desc_file,"set_create_desc_file",ERR_CODE_SET_DESC},

+ 4 - 4
dtu/dtu_main_t536/app/defineSys.h

@@ -12,7 +12,7 @@
 #ifndef _DEFINE_SYS_H
 #define _DEFINE_SYS_H
 
-#define DEVICE_VERSION_INFORMATION "NW24_20251219_003" // NW2022意思是按照22年南网标准文件(总调)来做的
+#define DEVICE_VERSION_INFORMATION "NW24_20251223_008" // NW2022意思是按照22年南网标准文件(总调)来做的
 
 #ifdef ___defineSys____//!!!此宏定义不开启,以下宏不直接开启,只用于注释显示
 
@@ -54,11 +54,11 @@
 #define VOLT_ADAPTIVE_FACTOR           // 电压系数自适应
 #define BATTERY_WITH_COMM              // 带通讯电源模块
 #define BATTERY_BP_L500			       // 无锡市欧瑞杰TX-BPL500W24D
-#define FUN_JDXX                       // 功能:小电流接地					版本:V1.0
+#define FUN_JDXX                       // 功能:小电流接地 版本:V1.0
 #define DISP_LIST_NUM                  // 列表类型定值显示定值选项的序号(如:"0:退出"、"1:投入")
 #define GEN_QUEUE                      // 录波相关
-#define RCD_STRAN_M                    /*录波传输*/
-#define RCD_STRAN_S                    /*录波传输*/
+#define RCD_STRAN_M                    // 录波传输
+#define RCD_STRAN_S                    // 录波传输
 #define FUN_FUXI_ESAM                  // 南网加密芯片
 #define FUNC_GET_RD_ONLY               // lcd_menu可配置只读定值
 #define FUNC_YT_HARD_YB                // lcd_menu新增关键硬件遥信(如常规保护硬压板、FA硬压板等)

+ 14 - 13
dtu/dtu_main_t536/app/equ.c

@@ -412,7 +412,7 @@ int equ_config_check(void)
 		BOARD_TYPE_FUXI_DI,
 		BOARD_TYPE_FUXI_DO,
 		BOARD_TYPE_FUXI_AC,
-		-1,
+		BOARD_TYPE_FUXI_24LED,
 		-1,
 		-1,
 		-1,
@@ -422,20 +422,19 @@ int equ_config_check(void)
 		-1,			
 	};
 
-	for(i=0;i<EQU_SLOT_NUM_MAX;i++)
-	{
-		if(bank_cfg[i] != -1 && bank_cfg[i]!=g_board_info[i].type)
-		{
-			char *name;
-			
-			b_err=true;
-			name = equ_info_brd_type(g_board_info[i].type);
-			rt_printf("通道配置错误:slot=%d,当前类型=%s,应该配成%s\r\n",i,(name==NULL)?"无":name,equ_info_brd_type(bank_cfg[i]));
-		}
-	}
+    for (i = 0; i < EQU_SLOT_NUM_MAX; i++)
+    {
+        if (bank_cfg[i] != -1 && bank_cfg[i] != g_board_info[i].type)
+        {
+            char *name;
 
-	return (b_err?-1:0);
+            b_err = true;
+            name = equ_info_brd_type(g_board_info[i].type);
+            rt_printf("通道配置错误:slot=%d, 当前类型=%s, 应该配成%s\r\n", i, (name == NULL) ? "无" : name, equ_info_brd_type(bank_cfg[i]));
+        }
+    }
 
+    return (b_err ? -1 : 0);
 }
 
 /******************************************************************************
@@ -546,6 +545,8 @@ int equ_init(void)
 		return -4;
 	}
 
+    equ_init_di();
+
 	return 0;
 }
 

+ 13 - 0
dtu/dtu_main_t536/app/main.c

@@ -156,6 +156,7 @@ int app_main (void *unused)
               	"app_main_loop", (int)getpid(), (int)syscall(SYS_gettid));
 #endif
 
+#if (1) /* 打印信息测试函数 */
 	dp_info_nt("最大定值个数 MAX_SET_NUMBER = %d", MAX_SET_NUMBER);
 	dp_info_nt("装置参数 EQUIP_PARA_NUMBER = %d, PARA_NUM = %d", EQUIP_PARA_NUMBER, PARA_NUM);
 	dp_info_nt("保护定值 SW_SET_NUMBER = %d, SW_SET_NUMBER = %d", SW_SET_NUMBER, SW_SET_NUMBER);
@@ -163,6 +164,18 @@ int app_main (void *unused)
 	dp_info_nt("公共定值 PUB_SET_NUMBER = %d, SET_PUB_NUM = %d", PUB_SET_NUMBER, SET_PUB_NUM);
 	dp_info_nt("内部定值 CSTSET_NUMBER = %d, CSTSET_NUM = %d", CSTSET_NUMBER, CSTSET_NUM);
 	dp_info_nt("固有参数 FIXEDSET_TABLE_NUMBER = %d", FIXEDSET_TABLE_NUMBER);
+    msleep(100);
+    equ_info_printf();
+    msleep(100);
+    equ_info_printf_di();
+    msleep(100);
+    equ_info_printf_do();
+    msleep(100);
+    equ_info_printf_ac();
+    msleep(100);
+    factor_printf();
+    msleep(100);
+#endif
 
 	{
 		struct timespec ts;

+ 32 - 7
dtu/dtu_main_t536/app/switch.c

@@ -397,13 +397,6 @@ const s8 * g_pub_do_name[PUB_DO_NUM] =
 {
 	"电池活化",
 	"活化退出",
-	"开出03",
-	"开出04",
-	"开出05",
-	"开出06",
-	"开出07",
-	"开出08",
-	"开出09",
 
 	"电压合格率清零",
 	"预控开出",
@@ -483,6 +476,16 @@ const s8 * g_pub_do_name[PUB_DO_NUM] =
 #ifdef FUNC_RESET_EQU
 	"重启装置",
 #endif
+	"开出01",
+	"开出02",
+	"开出03",
+	"开出04",
+	"开出05",
+	"开出06",
+	"开出07",
+	"开出08",
+	"开出09",
+	"开出10",
 };
 
 const s8 * g_pub_led_name[PUB_LED_NUM]=
@@ -4201,6 +4204,28 @@ int sw_get_chnl_ps(int index,bool prim)
 	}
 	return 1;
 }
+
+/**
+ * @brief          将ms的时间戳转换为ns的结构体
+ * @author         lch (lch_work@foxmail.com)
+ * @version        1.0
+ * @date           20251222
+ * @param[in/out]  {type} _ull_timestamp_ms 
+ * @return         * struct timespec
+ * @retval         none
+ * 
+ * @warning        none
+ * @note           none
+ */
+void transform_msts_to_tts(uint64_t _ull_timestamp_ms, struct timespec *_t_ts)
+{
+    // 计算秒(整数除法)
+    _t_ts->tv_sec = _ull_timestamp_ms / 1000;
+
+    // 计算纳秒:毫秒部分 * 1,000,000
+    _t_ts->tv_nsec = (_ull_timestamp_ms % 1000) * 1000000;
+}
+
 /*------------------------------ 测试函数 -------------------------------------
 一个实体文件必须带一个本模块的测试函数来进行单元测试,如果的确不方便在本模块中
 进行单元测试,必须在此注明实际的测试位置(例如在哪个实体文件中使用哪个测试函数).

+ 15 - 11
dtu/dtu_main_t536/app/switch.h

@@ -50,7 +50,7 @@ enum
 
 enum
 {
-    SW_DI_KRHW = 0,  // 合位 1
+    SW_DI_KRHW = 0,  // 合位
     SW_DI_KRTW,      // 分位
     SW_DI_WCN,       // 弹簧未储能
     SW_DI_YCN,       // 弹簧已储能
@@ -59,7 +59,7 @@ enum
     SW_DI_JDDZ_HW,   // 接地刀合位
     SW_DI_JDDZ_FW,   // 接地刀分位
     SW_DI_QYD_GJ,    // SF6气压低告警
-    SW_DI_QYD_BS,    // SF6气压低闭锁 10
+    SW_DI_QYD_BS,    // SF6气压低闭锁
     SW_DI_BHZTT,     // 自动化投入
     SW_DI_BHTT,      // 常规保护
     SW_DI_JZS_TT,    // 集中式
@@ -70,7 +70,7 @@ enum
     SW_DI_FA_BS_TT,  // 就地FA闭锁
     SW_DI_FA_LS,     // 联络/分段模式
     SW_DI_YYXH,      // 带电显示器有压
-    SW_DI_YB_FZ,     // 分闸出口压板状态 20
+    SW_DI_YB_FZ,     // 分闸出口压板状态
     SW_DI_YB_HZ,     // 合闸出口压板状态
     SW_DI_SH,        // 手动合闸
     SW_DI_SF,        // 手动分闸
@@ -121,7 +121,7 @@ enum
 	SW_RST_SY,		//瞬压复归
 	SW_RST_SY1,		//瞬压复归
 	SW_FBT_SY,		//瞬压闭锁
-	SW_DO_CN,		//储能信号//SW_DO_11,		
+	SW_DO_CN,		//储能信号		
 	SW_DO_BHDZ,		
 	SW_DO_TQBS,
 #ifdef	CUSTOMIZE_BZT //备自投
@@ -387,13 +387,6 @@ enum
 {
 	PUB_DO_DCHH = 0,// 电池活化
 	PUB_DO_HHTC,	// 活化退出
-	PUB_DO_03,		
-	PUB_DO_04,		
-	PUB_DO_05,		
-	PUB_DO_06,		
-	PUB_DO_07,		
-	PUB_DO_08,	
-	PUB_DO_09,
 
 	PUB_QUA_CLR,		
 	PUB_DO_YK,		//预控
@@ -461,6 +454,16 @@ enum
 #ifdef FUNC_RESET_EQU
 	PUB_RESET_EQU,			//重启装置
 #endif
+	PUB_DO_01,		
+	PUB_DO_02,		
+	PUB_DO_03,		
+	PUB_DO_04,		
+	PUB_DO_05,		
+	PUB_DO_06,		
+	PUB_DO_07,		
+	PUB_DO_08,	
+	PUB_DO_09,
+	PUB_DO_10,
 	PUB_DO_NUM,
 };
 
@@ -830,6 +833,7 @@ int sw_get_chnl_ps(int index,bool prim);
  int sw_ext_init(void);
  
 void _sw_cal_Xfl120( int ui_index, struct ui120 *pII);
+extern void transform_msts_to_tts(uint64_t _ull_timestamp_ms, struct timespec *_t_ts);
 
 #endif //_SWITCH_H
 

+ 173 - 140
dtu/dtu_main_t536/main_mod.c

@@ -282,112 +282,144 @@ int mod_init(void)
 extern void gps_isr(void);
 int di_do_adc (void *unused)
 {
-	pid_t tid;
+    pid_t tid;
     cpu_set_t set;
     struct sched_param sch_par;
     sch_par.sched_priority = 90;
 
-	// Set CPU affinity [T536-CPU-3]
+    // Set CPU affinity [T536-CPU-3]
     tid = gettid();
     CPU_ZERO(&set);
     CPU_SET(3, &set);
     sched_setaffinity(tid, sizeof(cpu_set_t), &set);
 
-	while(SystemInit_finish_flag == false)
-	{
-		msleep(10);
-	}
+    while (SystemInit_finish_flag == false)
+    {
+        msleep(10);
+    }
 
     uint32_t wdt_id;
-    int rc = watchdog_add_item("di_do_adc", &wdt_id,120);
-    if(rc != 0) {
+    int rc = watchdog_add_item("di_do_adc", &wdt_id, 120);
+    if (rc != 0)
+    {
         printf("can not add di_do_adc task to wdt\r\n");
         return -1;
     }
 
-    //adc_init();
-    dido_init();
-	rt_stat_init(&g_stat_periodus_5ms, "pit_5ms_priod(1us)");
-    pthread_setschedparam(pthread_self(), SCHED_FIFO, &sch_par);   // 设置当前线程优先级
-	prctl(PR_SET_NAME, "di_do_adc");
+    rt_stat_init(&g_stat_periodus_5ms, "pit_5ms_priod(1us)");
+    pthread_setschedparam(pthread_self(), SCHED_FIFO, &sch_par); // 设置当前线程优先级
+    prctl(PR_SET_NAME, "di_do_adc");
 #ifdef RT_THREAD_DEBUG
-	rt_printf("Thread created successfully: %s, PID: %d LWP: %d\r\n", 
-              	"di_do_adc", (int)getpid(), (int)syscall(SYS_gettid));
+    rt_printf("Thread created successfully: %s, PID: %d LWP: %d\r\n",
+              "di_do_adc", (int)getpid(), (int)syscall(SYS_gettid));
 #endif
 
-	// zhl add
-	struct shmem_fd shmem_fd;
-	if (share_mem_init_v2(&shmem_fd) < 0){
-		dp_err_n_c("--->shmem_init fail !!!");
-		return -1;
-	} else {
-		dp_info_n_c("--->shmem_init success !!!");
-	}
+#ifdef CPU_FUXI
+    // zhl add
+    struct shmem_fd shmem_fd;
+    if (share_mem_init_v2(&shmem_fd) < 0)
+    {
+        dp_err_n_c("--->shmem_init fail !!!");
+        return -1;
+    }
+    else
+    {
+        dp_info_n_c("--->shmem_init success !!!");
+    }
 
-	// 装置类型us_machine_type (分布式:1,集中式:2)
-	struct t_shmdata_machine_type machine_type = {0};
-	machine_type.us_machine_type = 1;
-	shm_packet_write_v2(SHM_ADDR_R_MACHINETYPE, (uint8_t *)&machine_type, sizeof(struct t_shmdata_machine_type));	
-	// printf("write SHM_ADDR_R_MACHINETYPE::0x%X -> us_updata: %d, us_op: %d, us_op_bk: %d, us_machine_type: %d, us_crc: 0x%04x\n\n", 
-	// 		SHM_ADDR_R_MACHINETYPE, machine_type.us_updata, machine_type.us_op, machine_type.us_op_bk, machine_type.us_machine_type, machine_type.us_crc);
-	
-	sleep(5); // 注:下发装置类型后,需要等待大于5s,才能读取到R核的ADC初始化标志信息
-	// ADC初始化标志信息
-	struct t_shmdata_flag adc_flag = {0};
-	int ret_flag = shm_packet_read_v2(SHM_ADDR_W_FLAG, sizeof(adc_flag), (uint8_t *)&adc_flag, sizeof(adc_flag));
-	if(adc_flag.us_cfg_adc_err == 1 || ret_flag < 0){
-		rt_err_set(ERR_CODE_INIT_ADC, 0);
-	}
-    else {
-	    dp_info_nt("adc init ok!");
-    }	
-	// printf("ret_flag: %d, read SHM_ADDR_W_FLAG:0x%X -> us_updata: %u, us_op: %u, us_op_bk: %u, us_cfg_adc_err: %u, us_crc: 0x%04x\n\n", 
-	// 		ret_flag, SHM_ADDR_W_FLAG, adc_flag.us_updata, adc_flag.us_op, adc_flag.us_op_bk, adc_flag.us_cfg_adc_err, adc_flag.us_crc);
-		
-    while(1)
+    // 写入毫秒时间戳
+    struct t_shmdata_timestamp t_rv_msts;
+    struct timeval tv;
+
+    gettimeofday(&tv, NULL);
+    uint64_t milliseconds = (uint64_t)(tv.tv_sec * 1000 + tv.tv_usec / 1000);
+    t_rv_msts.ull_timestamp = milliseconds;
+    shm_packet_write_v2(SHM_ADDR_R_TIMESTAMP, (uint8_t *)&t_rv_msts, sizeof(struct t_shmdata_timestamp));
+
+    // 装置类型us_machine_type (分布式:1,集中式:2)
+    struct t_shmdata_machine_type t_rv_mt = {0};
+    t_rv_mt.us_machine_type = 1;
+    shm_packet_write_v2(SHM_ADDR_R_MACHINETYPE, (uint8_t *)&t_rv_mt, sizeof(struct t_shmdata_machine_type));
+    // printf("write SHM_ADDR_R_MACHINETYPE::0x%X -> us_updata: %d, us_op: %d, us_op_bk: %d, us_machine_type: %d, us_crc: 0x%04x\n\n",
+    // 		SHM_ADDR_R_MACHINETYPE, t_rv_mt.us_updata, t_rv_mt.us_op, t_rv_mt.us_op_bk, t_rv_mt.us_machine_type, t_rv_mt.us_crc);
+    sleep(5); // 注:下发装置类型后,需要等待大于5s,才能读取到R核的ADC初始化标志信息
+
+    // ADC初始化标志信息
+    struct t_shmdata_flag t_rv_adc = {0};
+    int ret_flag = shm_packet_read_v2(SHM_ADDR_W_FLAG, sizeof(t_rv_adc), (uint8_t *)&t_rv_adc, sizeof(t_rv_adc));
+    if (t_rv_adc.us_cfg_adc_err == 1 || ret_flag < 0)
     {
-		static u8 flags = 0;
-		static unsigned long us1 = 0;
-		unsigned long origin_ext = 0;
+        rt_err_set(ERR_CODE_INIT_ADC, 0);
+    }
+    else
+    {
+        dp_info_nt("adc init ok!");
+    }
+    // printf("ret_flag: %d, read SHM_ADDR_W_FLAG:0x%X -> us_updata: %u, us_op: %u, us_op_bk: %u, us_cfg_adc_err: %u, us_crc: 0x%04x\n\n",
+    // 		ret_flag, SHM_ADDR_W_FLAG, t_rv_adc.us_updata, t_rv_adc.us_op, t_rv_adc.us_op_bk, t_rv_adc.us_cfg_adc_err, t_rv_adc.us_crc);
+
+    int l_retrv_di = equ_init_rv_di();
+    if (0 > l_retrv_di)
+    {
+        rt_err_set(ERR_CODE_INIT_SOFTWARE, 0);
+    }
+    else
+    {
+        dp_info_nt("rvdi init ok!");
+    }
+#endif
+
+    while (1)
+    {
+        static u8 flags = 0;
+        static unsigned long us1 = 0;
+        unsigned long origin_ext = 0;
 
         usleep(1000);
-		// bsp_ustimer_delay(1000); // 1ms
+        // bsp_ustimer_delay(1000); // 1ms
 
-		// 检查是否需要退出。
-		if(g_exit_flag)
-		{
-			//complete_and_exit(&exit_completion2, 1);
-			break;
-		}
+        // 检查是否需要退出。
+        if (g_exit_flag)
+        {
+            // complete_and_exit(&exit_completion2, 1);
+            break;
+        }
 
-		origin_ext = bsp_ustimer_get_origin();
-		if (flags) {
-			rt_stat_in(&g_stat_periodus_5ms, (origin_ext - us1));
-		}
-		
-		watchdog_feed(wdt_id);
+        origin_ext = bsp_ustimer_get_origin();
+        if (flags)
+        {
+            rt_stat_in(&g_stat_periodus_5ms, (origin_ext - us1));
+        }
+
+        watchdog_feed(wdt_id);
 
         // adc_isr(0);
-		if(adc_flag.us_cfg_adc_err == 0 && ret_flag > 0)
-		{
-			adc_isr_new(0);	
-		}
-				
-		//保护计算
-        if(prt_flag)     
+        if (t_rv_adc.us_cfg_adc_err == 0 && ret_flag > 0)
+        {
+            adc_isr_new(0);
+        }
+
+        // 保护计算
+        if (prt_flag)
         {
             pit_5ms_main(0);
-            prt_flag=false;
+            prt_flag = false;
         }
 
+#ifdef CPU_FUXI
+        if (0 == l_retrv_di)
+        {
+            get_shm_didata();
+        }
+#endif
 
-		// gps_isr(); // zhl upadte 放在另一个线程跑
-		us1 = origin_ext;
-		flags = 1;
+        // gps_isr(); // zhl upadte 放在另一个线程跑
+        us1 = origin_ext;
+        flags = 1;
     }
-	watchdog_remove_item(wdt_id);
+    watchdog_remove_item(wdt_id);
 
-	return 0;
+    return 0;
 }
 
 //当装置修改app文件夹里面的文件时,需要调用该函数,以sync_cnt数减为0时,调用sync,写入flash,保存数文件。
@@ -447,106 +479,107 @@ static int sync_func(void *arg)
 
 int main(void)
 {
-	// pid_t pid;
+    // pid_t pid;
 
-	char *argv[] = { "/sbin/ifconfig", "eth1", "192.168.2.100",NULL};
- 	char *envp[] = { NULL };
+    char *argv[] = {"/sbin/ifconfig", "eth1", "192.168.2.100", NULL};
+    char *envp[] = {NULL};
 
-	// struct task_struct * ts;
-	// struct sched_param sp;
-	int ret;
+    // struct task_struct * ts;
+    // struct sched_param sp;
+    int ret;
 
-	SystemInit_finish_flag = false;
-	
-	//停止喂狗,让程序复位.在命令行中输入insmod f306.ko m_reset=1
-	if(m_reset==1)
-	{
-		rt_printf("watchdog_m_reset(1)...\n");
-		watchdog_m_reset(1);
-		return 0;
-	}
+    SystemInit_finish_flag = false;
+
+    // 停止喂狗,让程序复位.在命令行中输入insmod f306.ko m_reset=1
+    if (m_reset == 1)
+    {
+        rt_printf("watchdog_m_reset(1)...\n");
+        watchdog_m_reset(1);
+        return 0;
+    }
 
-	call_usermodehelper("/sbin/ifconfig", argv, envp, UMH_WAIT_PROC);
+    call_usermodehelper("/sbin/ifconfig", argv, envp, UMH_WAIT_PROC);
 
     rt_printf("\r\n");
     dp_info_nt("%s %s", __DATE__, __TIME__);
     dp_info_nt("版本信息: SV%02d.%03d %s", (VER_NUM >> 16) & 0XFF, VER_NUM & 0XFFF, DEVICE_VERSION_INFORMATION);
 
-	//if(mod_init() < 0)    //jack.liu 20200904 认证信息先不使用
-	//	return -1;
+    // if(mod_init() < 0)    //jack.liu 20200904 认证信息先不使用
+    //	return -1;
 
-	bsp_init();	// bsp必须先初始化  
-	rt_init();	// 实时系统后初始化
-	app_init();	// 应用初始化最后初始化
+    bsp_init(); // bsp必须先初始化
+    rt_init();  // 实时系统后初始化
+    app_init(); // 应用初始化最后初始化
     adc_init();
 
-	// 建立主函数入口线程
-	ret = pthread_create(&AW_DTU_PTHREAD_TAB[PTHREAD_MAIN_LOOP], NULL, (void *)mainloop_soft_isr, NULL);
-	if(ret)
-	{
-		rt_printf("mainloop_soft_isr thread create failed!\r\n");
-		rt_printf("ret = %d, err = %s\r\n", ret, strerror(ret));
-		memset((char *)&AW_DTU_PTHREAD_TAB,0,sizeof(AW_DTU_PTHREAD_TAB));
-		return ret;
-	}	
+    // 建立主函数入口线程
+    ret = pthread_create(&AW_DTU_PTHREAD_TAB[PTHREAD_MAIN_LOOP], NULL, (void *)mainloop_soft_isr, NULL);
+    if (ret)
+    {
+        rt_printf("mainloop_soft_isr thread create failed!\r\n");
+        rt_printf("ret = %d, err = %s\r\n", ret, strerror(ret));
+        memset((char *)&AW_DTU_PTHREAD_TAB, 0, sizeof(AW_DTU_PTHREAD_TAB));
+        return ret;
+    }
 
-	// 创建主循环线程
-	ret = pthread_create(&AW_DTU_PTHREAD_TAB[PTHREAD_MAIN_APP], NULL, (void *)app_main, NULL);
-	if(ret)
-	{
-	    rt_printf("app_main thread create failed!\r\n");
-		rt_printf("ret = %d, err = %s\r\n", ret, strerror(ret));
-		AW_DTU_PTHREAD_TAB[PTHREAD_MAIN_APP] = 0;
-		memset((char *)&AW_DTU_PTHREAD_TAB,0,sizeof(AW_DTU_PTHREAD_TAB));
-		return ret;
-	}
+    // 创建主循环线程
+    ret = pthread_create(&AW_DTU_PTHREAD_TAB[PTHREAD_MAIN_APP], NULL, (void *)app_main, NULL);
+    if (ret)
+    {
+        rt_printf("app_main thread create failed!\r\n");
+        rt_printf("ret = %d, err = %s\r\n", ret, strerror(ret));
+        AW_DTU_PTHREAD_TAB[PTHREAD_MAIN_APP] = 0;
+        memset((char *)&AW_DTU_PTHREAD_TAB, 0, sizeof(AW_DTU_PTHREAD_TAB));
+        return ret;
+    }
 
 #if 1
-	// 创建三遥线程
-	ret = pthread_create(&AW_DTU_PTHREAD_TAB[PTHREAD_MAIN_DIDO_ADC], NULL, (void *)di_do_adc, NULL);
-	if(ret)
-	{
-	    rt_printf("di_do_adc thread create failed!\r\n");
-		rt_printf("ret = %d, err = %s\r\n", ret, strerror(ret));
-		AW_DTU_PTHREAD_TAB[PTHREAD_MAIN_DIDO_ADC] = 0;
-		memset((char *)&AW_DTU_PTHREAD_TAB,0,sizeof(AW_DTU_PTHREAD_TAB));
-		return ret;
-	}
+    // 创建三遥线程
+    ret = pthread_create(&AW_DTU_PTHREAD_TAB[PTHREAD_MAIN_DIDO_ADC], NULL, (void *)di_do_adc, NULL);
+    if (ret)
+    {
+        rt_printf("di_do_adc thread create failed!\r\n");
+        rt_printf("ret = %d, err = %s\r\n", ret, strerror(ret));
+        AW_DTU_PTHREAD_TAB[PTHREAD_MAIN_DIDO_ADC] = 0;
+        memset((char *)&AW_DTU_PTHREAD_TAB, 0, sizeof(AW_DTU_PTHREAD_TAB));
+        return ret;
+    }
 
     // 创建采样数据计算线程
     ret = pthread_create(&AW_DTU_PTHREAD_TAB[PTHREAD_CAL_SAMPLE], NULL, (void *)cal_thread, NULL);
-    if(ret)
+    if (ret)
     {
         rt_printf("cal_thread thread create failed!\r\n");
         rt_printf("ret = %d, err = %s\r\n", ret, strerror(ret));
         AW_DTU_PTHREAD_TAB[PTHREAD_CAL_SAMPLE] = 0;
-        memset((char *)&AW_DTU_PTHREAD_TAB,0,sizeof(AW_DTU_PTHREAD_TAB));
+        memset((char *)&AW_DTU_PTHREAD_TAB, 0, sizeof(AW_DTU_PTHREAD_TAB));
         return ret;
     }
 
-	ret = pthread_create(&sync_tid, NULL, (void *)sync_func, NULL);
-	if(ret)
-	{
-		rt_printf("ret = %d, err = %s\r\n", ret, strerror(ret));
-		sync_tid = 0;
-		return ret;
-	}
+    ret = pthread_create(&sync_tid, NULL, (void *)sync_func, NULL);
+    if (ret)
+    {
+        rt_printf("ret = %d, err = %s\r\n", ret, strerror(ret));
+        sync_tid = 0;
+        return ret;
+    }
 
     // 设置进程名字
-    prctl( PR_SET_NAME, "AW_DTU_CALL", 0, 0, 0);
+    prctl(PR_SET_NAME, "AW_DTU_CALL", 0, 0, 0);
 
     signal(SIGINT, main_mod_exit);
 #endif
 #ifdef RT_THREAD_DEBUG
-    rt_printf("thread create success!\r\n"); 
+    rt_printf("thread create success!\r\n");
 #endif
-    
-	// 主线程阻塞
-	while(1) {
-		usleep(1000*100);
-	}
 
-	return 0;	
+    // 主线程阻塞
+    while (1)
+    {
+        usleep(1000 * 100);
+    }
+
+    return 0;
 }
 
 int net_debug_exit(void);

Some files were not shown because too many files changed in this diff