equ_fuxi.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. /******************************************************************************
  2. 版权所有:
  3. 文件名称: equ.c
  4. 文件版本: 01.01
  5. 创建作者: sunxi
  6. 创建日期: 2013-03-25
  7. 功能说明: 装置信息管理维护
  8. 其它说明:
  9. 修改记录:
  10. */
  11. /*------------------------------- 头文件 --------------------------------------
  12. */
  13. #include "head.h"
  14. /*------------------------------- 宏定义 --------------------------------------
  15. */
  16. #define EQU_SLOT_CHECK_TIMEOUT 4 // 子板检查超时,以秒为单位,不能小于4s
  17. /*------------------------------ 类型结构 -------------------------------------
  18. */
  19. // 子板信息帧结构
  20. struct board_info_frame
  21. {
  22. u8 type; // 子板类型
  23. u8 status : 4; // 子板状态
  24. u8 errcode : 4; // 子板错误代码
  25. u16 crc; // 子板CRC
  26. u32 version; // 子板版本
  27. };
  28. /*------------------------------ 全局变量 -------------------------------------
  29. */
  30. // 控制板类型
  31. u32 g_brd_type_kz;
  32. // 采样板索引和插槽的对应关系
  33. const int g_ac_index_to_slot[EQU_SLOT_AC_NUM] = {1};
  34. // 采样板起始槽位,每种机箱不一样。
  35. u32 g_ac_slot_begin;
  36. // 记录频率对应ui通道的索引值
  37. int g_ui_freq[CFG_FREQ_NUM];
  38. // 模拟量对应关系
  39. static const s8 g_ac_index[BOARD_TYPE_KZ_NUM][EQU_SLOT_AC_CHN] =
  40. {
  41. {0X01, 0X03, 0X05, 0X07, 0XFF, 0XFF, 0XFF, 0XFF, 0X00, 0X02, 0X04, 0X06, 0X0E, 0X0C, 0X0A, 0X08}, // 24款分布式 lch
  42. };
  43. // 遥信转换表
  44. s8 g_change_di_index[BOARD_TYPE_KZ_NUM][EQU_DB_YX_NUM] =
  45. {
  46. {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},
  47. };
  48. // 开出对应关系
  49. static const s8 g_do_index[BOARD_TYPE_KZ_NUM][DO_NUM] =
  50. {
  51. {0, 1, 2, 3, 4, 5, 6, 7, 8, -1},
  52. };
  53. /*------------------------------ 函数声明 -------------------------------------
  54. */
  55. unsigned int change_di_ch(unsigned int di)
  56. {
  57. register int i, rts = 0;
  58. #if 0
  59. static int di_bak;
  60. if(di_bak!=di)
  61. {
  62. rt_printf_time("change_di_ch di=%x \r\n",di);
  63. di_bak=di;
  64. }
  65. #endif
  66. for (i = 0; i < EQU_DB_YX_NUM; i++)
  67. {
  68. if (g_change_di_index[g_brd_type_kz][i] != 0 && g_change_di_index[g_brd_type_kz][i] <= EQU_DB_YX_NUM)
  69. {
  70. if (di >> (g_change_di_index[g_brd_type_kz][i] - 1) & 0x01)
  71. rts |= (1 << i);
  72. }
  73. }
  74. // rt_printf("%d %d 。。",rts,g_brd_type_kz);
  75. return rts;
  76. }
  77. /*------------------------------ 外部函数 -------------------------------------
  78. 外部函数供其它实体文件引用,必须仔细检查传入参数的合法性.
  79. */
  80. /**
  81. * @brief 远动参数投入之后 遥信防抖时间的更新
  82. * @return * int
  83. * @retval none
  84. *
  85. * @warning none
  86. * @note none
  87. */
  88. int equ_config_di_yd(void)
  89. {
  90. u32 i;
  91. struct equ_config_di *ecd;
  92. // 用户配置的保持时间、拥有者、类型
  93. ecd = g_equ_config_di;
  94. for (i = 0; i < g_equ_config->di_num; i++)
  95. {
  96. g_di_st[ecd->slot][ecd->index].tm_filter = (u32)tRunPara.wYXFD;
  97. ecd++;
  98. }
  99. return 0;
  100. }
  101. int equ_config_do_yd(void)
  102. {
  103. int i, index;
  104. struct equ_config_do *ecd;
  105. // 用户配置的保持时间
  106. ecd = g_equ_config_do;
  107. for (i = 0; i < g_equ_config->do_num; i++)
  108. {
  109. u32 dotime = (u32)ecd->time_pulse;
  110. if (ecd->slot == g_do_slot)
  111. {
  112. // 如果定值参数中设置了分闸时间,覆盖
  113. if (ecd->owner && ((ecd->type == (SW_DO_BHT + 1)) || (ecd->type == (SW_DO_YKT + 1))))
  114. {
  115. if (pRunSet->bTT_RmtPara)
  116. {
  117. dotime = tRunPara.wFZMC;
  118. }
  119. }
  120. // 如果定值参数中设置了合闸时间,覆盖
  121. if (ecd->owner && ((ecd->type == (SW_DO_BHH + 1)) || (ecd->type == (SW_DO_YKH + 1))))
  122. {
  123. if (pRunSet->bTT_RmtPara)
  124. {
  125. dotime = tRunPara.wHZMC;
  126. }
  127. }
  128. index = equ_get_do_channel(ecd->index);
  129. g_do_st[index].us_keep = (u32)dotime;
  130. g_do_st[index].us_keep *= 1000; // ms转换为us
  131. dp_err_n_c("g_do_st[%d].us_keep = %d", index, g_do_st[index].us_keep);
  132. }
  133. ecd++;
  134. }
  135. return 0;
  136. }
  137. int equ_init_di(void)
  138. {
  139. int i, ui;
  140. struct equ_config_di *ecd;
  141. // 采样板起始槽位
  142. g_ac_slot_begin = EQU_SLOT_AC_BEGIN;
  143. #if !defined CPU_FUXI /* 注意t536版fuxi不使用这个配置 */
  144. // 检查频率硬件通道对应的UI。
  145. g_ui_freq[0] = UI_NUM;
  146. g_ui_freq[1] = UI_NUM;
  147. for (i = 0; i < g_equ_config->ac_num; i++)
  148. {
  149. // 频率通道必须是配置了的公共电压类型
  150. if (g_equ_config_ac[i].type == 0 || g_equ_config_ac[i].owner != 0)
  151. {
  152. continue;
  153. }
  154. ui = g_equ_config_ac[i].type - 1;
  155. if (ui >= PUB_AC_NUM)
  156. {
  157. continue;
  158. }
  159. // 确定频率对应电压通道
  160. if (ui < PUB_AC_NUM)
  161. {
  162. if (g_equ_config_ac[i].slot == 9 && g_equ_config_ac[i].index == 0)
  163. {
  164. g_ui_freq[0] = ui;
  165. }
  166. if (g_equ_config_ac[i].slot == 10 && g_equ_config_ac[i].index == 0)
  167. {
  168. g_ui_freq[1] = ui;
  169. }
  170. }
  171. }
  172. #else
  173. g_ui_freq[0] = PUB_AC_UA1;
  174. g_ui_freq[1] = PUB_AC_UA2;
  175. #endif
  176. // 初始化开入g_di_st结构
  177. memset((unsigned char *)g_di_st, 0, sizeof(g_di_st));
  178. ecd = g_equ_config_di;
  179. for (i = 0; i < g_equ_config->di_num; i++)
  180. {
  181. g_di_st[ecd->slot][ecd->index].tm_filter = ecd->filter_time;
  182. g_di_st[ecd->slot][ecd->index].owner = ecd->owner;
  183. g_di_st[ecd->slot][ecd->index].type = ecd->type;
  184. ecd++;
  185. }
  186. return 0;
  187. }
  188. int equ_config_do_keeptime(void)
  189. {
  190. u32 i, index;
  191. struct equ_config_do *ecd;
  192. memset(&g_do_st, 0, sizeof(struct do_struct) * DO_NUM);
  193. // 用户配置的保持时间
  194. ecd = g_equ_config_do;
  195. for (i = 0; i < g_equ_config->do_num; i++)
  196. {
  197. if (ecd->slot == g_do_slot)
  198. {
  199. index = equ_get_do_channel(ecd->index);
  200. g_do_st[index].us_keep = (u32)ecd->time_pulse;
  201. g_do_st[index].us_keep *= 1000; // ms转换为us
  202. }
  203. ecd++;
  204. }
  205. return 0;
  206. }
  207. #ifdef BSP_CAN_ENABLE
  208. /******************************************************************************
  209. 函数名称: equ_board_info_update
  210. 函数版本: 01.01
  211. 创建作者: sunxi
  212. 创建日期: 2013-08-08
  213. 函数说明: 接收到子板的对时应答帧后,更新子板信息
  214. 参数说明:
  215. can_bus 从哪条can总线接收到的帧。
  216. frame 接收帧的buf指针
  217. 返回值:
  218. 0: 成功
  219. 其它: 失败
  220. 修改记录:
  221. */
  222. int equ_board_info_update(int can_bus, u8 *frame)
  223. {
  224. struct can_frame_head *cfh;
  225. struct board_info_frame *bif;
  226. struct board_info *bi;
  227. // 检查帧内容
  228. cfh = (struct can_frame_head *)frame;
  229. #ifdef CAN_SLAVE_BOARD
  230. if (cfh->src >= (EQU_SLOT_NUM_MAX + CAN_BOARD_NUM))
  231. #else
  232. if (cfh->src >= EQU_SLOT_NUM_MAX)
  233. #endif
  234. {
  235. return -1;
  236. }
  237. if (cfh->len != 8)
  238. {
  239. return -2;
  240. }
  241. // 比较子板类型
  242. bi = &g_board_info[cfh->src];
  243. bif = (struct board_info_frame *)(frame + sizeof(cfh));
  244. if (bif->type != bi->type)
  245. {
  246. // rt_printf("board type error(no=%d,bi_type=%d,gbi_type=%d)\r\n",cfh->src,bif->type,bi->type);
  247. // print_mem("frame",frame,16);
  248. return -3;
  249. }
  250. // 得到子板信息
  251. bi->status = bif->status;
  252. bi->errcode = bif->errcode;
  253. bi->crc = bif->crc;
  254. bi->version = bif->version;
  255. // rt_printf("%02d\t%02d\t%02d\t%04x\t%08x\t",bi->type,bi->status,bi->errcode,bi->crc,bi->version);
  256. // 得到子板时间
  257. clk_time_get(&bi->update_time);
  258. bi->us0 = ustimer_get_origin();
  259. bi->is_ok = 1;
  260. bi->can_bus = can_bus;
  261. return 0;
  262. }
  263. #endif
  264. /******************************************************************************
  265. 函数名称: equ_ac_channel_is_ok
  266. 函数版本: 01.01
  267. 创建作者: sunxi
  268. 创建日期: 2013-08-08
  269. 函数说明: 得到插槽中子板的模拟量通道对应的ADC采样通道。
  270. 参数说明:
  271. slot 插槽索引号
  272. index 子板上模拟量通道索引号
  273. 返回值: ADC采样通道索引号
  274. 修改记录:
  275. */
  276. int equ_ac_channel_is_ok(u32 index)
  277. {
  278. // 检查参数
  279. if (index >= CFG_ADC_CHANNEL)
  280. {
  281. return 0;
  282. }
  283. // 直接返回ok 板卡没有配置检测io
  284. return 1;
  285. // return g_ac_slot_is_ok[index/EQU_SLOT_AC_CHN];
  286. }
  287. /******************************************************************************
  288. 函数名称: equ_get_ac_channel
  289. 函数版本: 01.01
  290. 创建作者: sunxi
  291. 创建日期: 2013-08-08
  292. 函数说明: 得到插槽中子板的模拟量通道对应的ADC采样通道。
  293. 参数说明:
  294. slot 插槽索引号
  295. index 子板上模拟量通道索引号
  296. 返回值: ADC采样通道索引号
  297. 修改记录:
  298. */
  299. int equ_get_ac_channel(u32 slot, u32 index)
  300. {
  301. // 检查参数
  302. #if (0) /* 不检查 插槽索引号 lch 2025年12月5日17:29:28 */
  303. if (slot != BOARD_TYPE_FUXI_AC)
  304. {
  305. return -1;
  306. }
  307. #endif
  308. if (index >= CFG_ADC_CHANNEL)
  309. {
  310. return -2;
  311. }
  312. return g_ac_index[g_brd_type_kz][index];
  313. }
  314. /******************************************************************************
  315. 函数名称: equ_get_ac_slot
  316. 函数版本: 01.01
  317. 创建作者: xxxxxx
  318. 创建日期: 2014-10-09
  319. 函数说明: 得到采样通道对应的板卡
  320. 参数说明:
  321. owner 归属公共、开关
  322. type 采样类型
  323. 返回值: ADC采样通道索引号
  324. 修改记录:
  325. */
  326. int equ_get_ac_slot(u32 owner, u32 type)
  327. {
  328. u32 no;
  329. if (owner)
  330. {
  331. no = g_sw[owner].ac_cfg_index[type];
  332. }
  333. else
  334. {
  335. no = g_sw_pub.ac_cfg_index[type];
  336. }
  337. return g_equ_config_ac[no].slot;
  338. }
  339. /******************************************************************************
  340. 函数名称: equ_ac_index_to_slot
  341. 函数版本: 01.01
  342. 创建作者: sunxi
  343. 创建日期: 2013-08-08
  344. 函数说明: 将采样板索引号(和ADC通道号对应)转换为插槽号。
  345. 参数说明:
  346. ac_index 采样板索引号
  347. 返回值: 插槽号
  348. 修改记录:
  349. */
  350. int equ_ac_index_to_slot(int ac_index)
  351. {
  352. if ((u32)ac_index >= EQU_SLOT_AC_NUM)
  353. {
  354. return 0;
  355. }
  356. return g_ac_index_to_slot[ac_index];
  357. }
  358. /******************************************************************************
  359. 函数名称: equ_get_do_channel
  360. 函数版本: 01.01
  361. 创建作者: sunxi
  362. 创建日期: 2013-08-08
  363. 函数说明: 配置子板上的开出资源
  364. 参数说明:
  365. slot 插槽索引号
  366. 返回值: 插槽号
  367. 0: 成功
  368. 其它: 失败
  369. 修改记录:
  370. */
  371. int equ_get_do_channel(u32 index)
  372. {
  373. return g_do_index[g_brd_type_kz][index];
  374. }
  375. #ifdef CPU_FUXI
  376. /**
  377. * @brief 初始化rv核数据
  378. * @author lch (lch_work@foxmail.com)
  379. * @version 1.0
  380. * @date 20251222
  381. * @return * int
  382. * @retval none
  383. *
  384. * @warning none
  385. * @note none
  386. */
  387. int equ_init_rv_di(void)
  388. {
  389. struct t_shmdata_di_astime t_di_cfg = {0};
  390. struct equ_config_di *ecd;
  391. ecd = g_equ_config_di;
  392. for (int i = 0; i < g_equ_config->di_num; i++)
  393. {
  394. t_di_cfg.us_as_time[i] = g_di_st[ecd->slot][ecd->index].tm_filter;
  395. // rt_printf("[%02d] g_di_st[%02d][%02d].tm_filter = %d\r\n", i, ecd->slot, ecd->index, g_di_st[ecd->slot][ecd->index].tm_filter);
  396. ecd++;
  397. }
  398. return shm_packet_write_v2(SHM_ADDR_R_DI_ASTIME, (uint8_t *)&t_di_cfg, sizeof(struct t_shmdata_di_astime));
  399. }
  400. /**
  401. * @brief 初始化rv核数据
  402. * @author lch (lch_work@foxmail.com)
  403. * @version 1.0
  404. * @date 20251222
  405. * @return * int
  406. * @retval none
  407. *
  408. * @warning none
  409. * @note none
  410. */
  411. int equ_reinit_rv_di(void)
  412. {
  413. struct t_shmdata_di_astime t_di_cfg = {0};
  414. for (int i = 0; i < g_equ_config->di_num; i++)
  415. {
  416. t_di_cfg.us_as_time[i] = tRunPara.wYXFD;
  417. }
  418. return shm_packet_write_v2(SHM_ADDR_R_DI_ASTIME, (uint8_t *)&t_di_cfg, sizeof(struct t_shmdata_di_astime));
  419. }
  420. #endif
  421. /*------------------------------ 内部函数 -------------------------------------
  422. 内部函数以下划线‘_’开头,不需要检查参数的合法性.
  423. */
  424. /*------------------------------ 测试函数 -------------------------------------
  425. 一个实体文件必须带一个本模块的测试函数来进行单元测试,如果的确不方便在本模块中
  426. 进行单元测试,必须在此注明实际的测试位置(例如在哪个实体文件中使用哪个测试函数).
  427. */
  428. /*------------------------------ 文件结束 -------------------------------------
  429. */