cboard_ac.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038
  1. #include "cboard.h"
  2. #include "datadef.h"
  3. #include "lock.h"
  4. #include "mb.h"
  5. #include "log.h"
  6. typedef struct {
  7. void* mb;
  8. lock_t lck;
  9. }cboard_handle_t;
  10. static cboard_handle_t cbHandle={0};
  11. static int read_reg(void *mb, uint8_t addr, uint16_t reg, uint16_t *data, int cnt)
  12. {
  13. return mb_read(mb, addr, reg, data, cnt, 800);
  14. }
  15. static int write_reg(cboard_handle_t *h, uint8_t addr, uint16_t reg, uint16_t *data, int cnt)
  16. {
  17. return mb_write(mb, addr, reg, data, cnt);
  18. }
  19. ////////////////////////////////////////////////////////////////////
  20. static int get_info(cboard_handle_t *h, int addr, ch_info_t *info)
  21. {
  22. int i,r=-1;
  23. uint16_t tmp=0;
  24. r = read_reg(h->mb, addr, POWER_AC_GET_INFO, &tmp, 1);
  25. if(r==0) {
  26. info->type = (tmp>>8)&0xFF;
  27. info->chs = tmp&0xFF;
  28. return 0;
  29. }
  30. r = read_reg(h->mb, addr, POWER_DC_INFO, &tmp, 1);
  31. if(r==0) {
  32. info->type = (tmp>>8)&0xFF;
  33. info->chs = tmp&0xFF;
  34. }
  35. return r;
  36. }
  37. static int get_ch(cboard_handle_t *h, int ch, power_ch_t *pch)
  38. {
  39. if(!pch || !h->all.pch || !h->all.chs || !h->all.pch[ch]) {
  40. lock_d_release(h->lck);
  41. return -1;
  42. }
  43. *pch = *h->all.pch[ch];
  44. return 0;
  45. }
  46. ////////////////////////////////////////////////////////////////
  47. static int set_open_delay(cboard_handle_t *h, int type, int addr, uint16_t delay)
  48. {
  49. switch(type) {
  50. case AC_SINGLE_S_TYPE:
  51. case AC_SINGLE_B_TYPE:
  52. {
  53. }
  54. break;
  55. case DCPDU_TYPE:
  56. {
  57. }
  58. break;
  59. case TREE_AC_TYPE:
  60. {
  61. }
  62. break;
  63. case AC_MULTI_S_TYPE:
  64. case AC_MULTI_B_TYPE:
  65. case DC_OUT_TYPE:
  66. case DC_IN_TYPE:
  67. default:
  68. return -1;
  69. }
  70. }
  71. static int set_close_delay(cboard_handle_t *h, int type, int addr, uint16_t delay)
  72. {
  73. switch(type) {
  74. case AC_SINGLE_S_TYPE:
  75. case AC_SINGLE_B_TYPE:
  76. {
  77. }
  78. break;
  79. case DCPDU_TYPE:
  80. {
  81. }
  82. break;
  83. case TREE_AC_TYPE:
  84. {
  85. }
  86. break;
  87. case AC_MULTI_S_TYPE:
  88. case AC_MULTI_B_TYPE:
  89. case DC_OUT_TYPE:
  90. case DC_IN_TYPE:
  91. default:
  92. return -1;
  93. }
  94. }
  95. static int set_kb_value(cboard_handle_t *h, int type, int addr, kb_val_t *kv)
  96. {
  97. switch(type) {
  98. case AC_SINGLE_S_TYPE:
  99. case AC_SINGLE_B_TYPE:
  100. {
  101. }
  102. break;
  103. case DCPDU_TYPE:
  104. {
  105. }
  106. break;
  107. case TREE_AC_TYPE:
  108. {
  109. }
  110. break;
  111. case AC_MULTI_S_TYPE:
  112. case AC_MULTI_B_TYPE:
  113. case DC_OUT_TYPE:
  114. case DC_IN_TYPE:
  115. default:
  116. return -1;
  117. }
  118. }
  119. static int reset_consump(cboard_handle_t *h, int type, int addr)
  120. {
  121. switch(type) {
  122. case AC_SINGLE_S_TYPE:
  123. case AC_SINGLE_B_TYPE:
  124. {
  125. }
  126. break;
  127. case DCPDU_TYPE:
  128. {
  129. }
  130. break;
  131. case TREE_AC_TYPE:
  132. {
  133. }
  134. break;
  135. case AC_MULTI_S_TYPE:
  136. case AC_MULTI_B_TYPE:
  137. case DC_OUT_TYPE:
  138. case DC_IN_TYPE:
  139. default:
  140. return -1;
  141. }
  142. }
  143. static int get_switch(cboard_handle_t *h, power_ch_t *pch)
  144. {
  145. int r=-1;
  146. switch(pch->info.type) {
  147. case AC_SINGLE_S_TYPE:
  148. {
  149. }
  150. break;
  151. case DCPDU_TYPE:
  152. {
  153. }
  154. break;
  155. case TREE_AC_TYPE:
  156. {
  157. }
  158. break;
  159. case AC_MULTI_S_TYPE:
  160. case AC_MULTI_B_TYPE:
  161. case DC_OUT_TYPE:
  162. case DC_IN_TYPE:
  163. default:
  164. return -1;
  165. }
  166. return r;
  167. }
  168. static int set_switch(cboard_handle_t *h, power_ch_t *pch)
  169. {
  170. int r=-1;
  171. uint16_t offset,tmp[2]={0},st=pch->power[0].status;
  172. if (pch->thr.v_upper.en == 1)
  173. st |= ENABLE_AC3_V_UP;
  174. if (pch->thr.v_lower.en == 1)
  175. st |= ENABLE_AC3_V_DOWN;
  176. if (pch->thr.c_upper.en == 1)
  177. st |= ENABLE_AC3_C_UP;
  178. if (pch->thr.p_upper.en == 1)
  179. st |= ENABLE_AC3_P_UP;
  180. if (pch->thr.w_upper.en == 1)
  181. st |= ENABLE_AC3_W_UP;
  182. switch(pch->info.type) {
  183. case AC_SINGLE_S_TYPE:
  184. case AC_SINGLE_B_TYPE:
  185. {
  186. offset = POWER_AC_CH_STAT_L+pch->info.ch;
  187. r = write_reg(h, pch->info.addr, offset, &st, 1);
  188. }
  189. break;
  190. case AC_MULTI_S_TYPE:
  191. case AC_MULTI_B_TYPE:
  192. case DC_OUT_TYPE:
  193. case DC_IN_TYPE:
  194. {
  195. }
  196. break;
  197. case DCPDU_TYPE:
  198. {
  199. uint16_t mask;
  200. offset = POWER_DC_STAT_INFO+pch->info.ch;
  201. mask = ~(1 << pch->info.ch);
  202. tmp[0] &= mask;
  203. tmp[0] |= (st << pch->info.ch);
  204. write_reg(h, pch->info.addr, offset, tmp, 2);
  205. }
  206. break;
  207. case TREE_AC_TYPE:
  208. {
  209. uint16_t reg;
  210. uint8_t pwr_type=paras_get()->prod.pwr_type;
  211. if(pwr_type==PDU_AC_I3O3 || pwr_type==PDU_AC_I3O1) {
  212. reg = POWER_AC3_OUT_ENABLE;
  213. }
  214. else {
  215. reg = POWER_AC3_CH_OUT_ENABLE;
  216. }
  217. tmp[0] = st;
  218. offset = reg + +pch->info.ch;
  219. r = write_reg(h, pch->info.addr, offset, tmp, 2);
  220. }
  221. break;
  222. default:
  223. return -1;
  224. }
  225. return r;
  226. }
  227. static int set_threshold(cboard_handle_t *h, power_ch_t *pch)
  228. {
  229. int r=-1;
  230. switch(pch->info.type) {
  231. case AC_SINGLE_S_TYPE:
  232. case AC_SINGLE_B_TYPE:
  233. {
  234. }
  235. break;
  236. case DCPDU_TYPE:
  237. {
  238. }
  239. break;
  240. case TREE_AC_TYPE:
  241. {
  242. }
  243. break;
  244. default:
  245. return -1;
  246. }
  247. return r;
  248. }
  249. //////////////////////////////////////////////////////////////////
  250. static int get_board(cboard_handle_t *h, uint8_t addr, board_data_t *pbrd)
  251. {
  252. int r,i,j;
  253. alarm_t alarm;
  254. uint16_t offset,tmp[144];
  255. switch(pbrd->type) {
  256. case AC_SINGLE_S_TYPE:
  257. case AC_SINGLE_B_TYPE:
  258. {
  259. uint32_t val;
  260. r = read_reg(h, pbrd->addr, POWER_AC_CUR_INFO_L, tmp, pbrd->chs);
  261. if(r==0 && pbrd->pch) {
  262. for (i=0; i<pbrd->chs; i++) {
  263. int idx = i * 12;
  264. // 解电压数据
  265. val = (tmp[1 + idx] << 16) | tmp[0 + idx];
  266. pbrd->pch[i].power[0].voltage = val / 1000.0;
  267. // 解电流数据
  268. val = (tmp[3 + idx] << 16) | tmp[2 + idx];
  269. pbrd->pch[i].power[0].current = val / 1000.0;
  270. // 解功率数据
  271. val = (tmp[5 + idx] << 16) | tmp[4 + idx];
  272. pbrd->pch[i].power[0].power = val / 1000.0;
  273. // 解频率数据
  274. val = (tmp[7 + idx] << 16) | tmp[6 + idx];
  275. pbrd->pch[i].power[0].freq = val / 1000.0;
  276. // 解耗电量数据
  277. val = (tmp[9 + idx] << 16) | tmp[8 + idx];
  278. pbrd->pch[i].power[0].consump = val / 1000.0;
  279. // 解功率因素数据
  280. val = (tmp[11 + idx] << 16) | tmp[10 + idx];
  281. pbrd->pch[i].power[0].factor = val / 1000.0;
  282. }
  283. }
  284. r = read_reg(h, pbrd->addr, POWER_AC_STAT_INFO_L, tmp, pbrd->chs);
  285. if (r < 0) {
  286. LOGE("get_board, addr:%d offset:%d r=%d\n", pbrd->addr, offset, r);
  287. return r;
  288. }
  289. if(pbrd->pch) {
  290. for (i=0; i<pbrd->chs; i++) {
  291. pbrd->pch[i].power[0].status = tmp[i] & (0x01);
  292. pbrd->pch[i].alarm.v_upper = tmp[i] & ALARM_V_UPPER;
  293. pbrd->pch[i].alarm.v_lower = tmp[i] & ALARM_V_LOWER;
  294. pbrd->pch[i].alarm.c_upper = tmp[i] & ALARM_C_UPPER;
  295. pbrd->pch[i].alarm.p_upper = tmp[i] & ALARM_P_UPPER;
  296. pbrd->pch[i].alarm.w_upper = tmp[i] & ALARM_W_UPPER;
  297. pbrd->pch[i].alarm.ph_loss = 0;
  298. }
  299. }
  300. }
  301. break;
  302. case DCPDU_TYPE:
  303. {
  304. uint32_t flag;
  305. offset = POWER_DC_OUT_INFO + 16;
  306. uint16_t *ptmp = tmp + 32;
  307. r = read_reg(h, pbrd->addr, offset, ptmp, 32);
  308. if (r < 0) {
  309. LOGE("get_board, addr:%d offset:%d r=%d\n", pbrd->addr, offset, r);
  310. return r;
  311. }
  312. for (i = 0; i < pbrd->chs; i++) {
  313. int Index = i * 8;
  314. // 解电压数据
  315. float value = (tmp[1 + Index] << 16) + tmp[0 + Index];
  316. pbrd->pch[i].power[0].voltage = value / 1000.0;
  317. // 解电流数据
  318. value = (tmp[3 + Index] << 16) + tmp[2 + Index];
  319. pbrd->pch[i].power[0].current = value / 1000.0;
  320. // 解功率数据
  321. value = (tmp[5 + Index] << 16) + tmp[4 + Index];
  322. pbrd->pch[i].power[0].power = value / 1000.0;
  323. value = (tmp[7 + Index] << 16) + tmp[6 + Index];
  324. pbrd->pch[i].power[0].consump = value / 1000.0;
  325. pbrd->pch[i].power[0].freq = 0;
  326. pbrd->pch[i].power[0].factor = 1;
  327. }
  328. offset = POWER_DC_STAT_INFO;
  329. r = read_reg(h, pbrd->addr, offset, tmp, 2);
  330. if (r < 0) {
  331. LOGE("get_board, addr:%d offset:%d r=%d\n", pbrd->addr, offset, r);
  332. return r;
  333. }
  334. for (i = 0; i < pbrd->chs; i++) {
  335. flag = (tmp[1] << 16) + tmp[0];
  336. pbrd->pch[i].power[0].status = (flag >> i) & 0x1;
  337. }
  338. // 获取报警状态
  339. offset = POWER_DC_WARNING;
  340. r = read_reg(h, pbrd->addr, offset, tmp, 16);
  341. if (r < 0) {
  342. LOGE("get_board, addr:%d offset:%d r=%d\n", pbrd->addr, offset, r);
  343. return r;
  344. }
  345. for (i = 0; i < pbrd->chs; i++) {
  346. int Index = i * 2;
  347. pbrd->pch[i].alarm.v_upper = tmp[0+Index] & BIT(0);
  348. pbrd->pch[i].alarm.v_lower = tmp[0+Index] & BIT(1);
  349. pbrd->pch[i].alarm.c_upper = tmp[0+Index] & BIT(2);
  350. pbrd->pch[i].alarm.p_upper = tmp[0+Index] & BIT(3);
  351. pbrd->pch[i].alarm.w_upper = tmp[0+Index] & BIT(4);
  352. }
  353. }
  354. break;
  355. case TREE_AC_TYPE:
  356. {
  357. uint8_t v=0;
  358. offset = POWER_AC3_OUT_INFO;
  359. r = read_reg(h, pbrd->addr, offset, tmp, 80);
  360. if (r < 0) {
  361. LOGE("get_board, addr:%d offset:%d r=%d\n", pbrd->addr, offset, r);
  362. return r;
  363. }
  364. offset = POWER_AC3_OUT_INFO+40;
  365. uint16_t* ptmp=tmp+80;
  366. r = read_reg(h, pbrd->addr, offset, ptmp, 64);
  367. if (r < 0) {
  368. LOGE("get_board, addr:%d offset:%d r=%d\n", pbrd->addr, offset, r);
  369. return r;
  370. }
  371. for (i=0; i<pbrd->chs; i++) {
  372. int Index = i * 16;
  373. // 解电压数据
  374. float value = (tmp[1+Index] << 16) + tmp[0+Index];
  375. pbrd->pch[i].power[0].voltage = value / 1000.0f;
  376. // 解电流数据
  377. value = (tmp[3+Index] << 16) + tmp[2+Index];
  378. pbrd->pch[i].power[0].current = value / 1000.0f;
  379. // 解功率数据
  380. value = (tmp[5+Index] << 16) + tmp[4+Index];
  381. pbrd->pch[i].power[0].power = value / 1000.0f;
  382. // 无功
  383. value = (tmp[7+Index] << 16) + tmp[6+Index];
  384. // 视在功率
  385. value = (tmp[9+Index] << 16) + tmp[8+Index];
  386. // 解频率数据
  387. value = (tmp[11+Index] << 16) + tmp[10+Index];
  388. pbrd->pch[i].power[0].freq = value / 1000.0f;
  389. // 解耗电量数据
  390. value = (tmp[13+Index] << 16) + tmp[12+Index];
  391. pbrd->pch[i].power[0].consump = value / 1000.0f;
  392. // 解功率因素数据
  393. value = (tmp[15+Index] << 16) + tmp[14+Index];
  394. pbrd->pch[i].power[0].factor = value / 1023.0f;
  395. }
  396. //获取通道开关状态及零线状态
  397. offset = POWER_AC3_OUT_ENABLE;
  398. r = read_reg(h, pbrd->addr, offset, tmp, 20);
  399. if (r < 0) {
  400. LOGE("get_board, addr:%d offset:%d r=%d\n", pbrd->addr, offset, r);
  401. return r;
  402. }
  403. for (i=0; i<pbrd->chs; i++) {
  404. int Index = i * 2;
  405. pbrd->pch[i].power[0].status = tmp[0+Index] & 0x01;
  406. pbrd->pch[i].power[0].nwire = tmp[18] & 0x01;
  407. }
  408. //获取故障状态
  409. offset = POWER_AC3_OUT_ERROR;
  410. r = read_reg(h, pbrd->addr, offset, tmp, 18);
  411. if (r < 0) {
  412. LOGE("get_board, addr:%d offset:%d r=%d\n", pbrd->addr, offset, r);
  413. return r;
  414. }
  415. for (i=0; i<pbrd->chs; i++) {
  416. int Index = i * 2;
  417. pbrd->pch[i].alarm.v_upper = tmp[0+Index] & BIT(0);
  418. pbrd->pch[i].alarm.v_lower = tmp[0+Index] & BIT(1);
  419. pbrd->pch[i].alarm.c_upper = tmp[0+Index] & BIT(2);
  420. pbrd->pch[i].alarm.p_upper = tmp[0+Index] & BIT(3);
  421. pbrd->pch[i].alarm.w_upper = tmp[0+Index] & BIT(4);
  422. }
  423. offset = POWER_AC3_ALARM_MISSING_PH;
  424. r = read_reg(h, pbrd->addr, offset, tmp, pbrd->chs);
  425. if (r < 0) {
  426. LOGE("get_board, addr:%d offset:%d r=%d\n", pbrd->addr, offset, r);
  427. return r;
  428. }
  429. v = 0;
  430. for(i = 0; i < 3; i++) {
  431. if(tmp[i * 2]>0) {
  432. v |= 1<<i;
  433. }
  434. }
  435. pbrd->ph_loss = v;
  436. }
  437. break;
  438. case AC_MULTI_S_TYPE:
  439. case AC_MULTI_B_TYPE:
  440. case DC_OUT_TYPE:
  441. case DC_IN_TYPE:
  442. default:
  443. return -1;
  444. }
  445. return 0;
  446. }
  447. int power_scan(int max_addr)
  448. {
  449. int r,i,j,idx=0,chs=0;
  450. ch_info_t info;
  451. cboard_handle_t *h=&cbHandle;
  452. LOGD("___ power scan start\n");
  453. lock_d_hold(h->lck);
  454. for(i=1; i<=max_addr; i++) {
  455. r = get_info(h, i, &info);
  456. LOGD("___ get_info from addr %d, return %d\n", i, r);
  457. if(r==0) {
  458. h->all.pbrd[i] = (board_data_t*)calloc(1, sizeof(board_data_t));
  459. if(h->all.pbrd[i]) {
  460. h->all.pbrd[i]->type = info.type;
  461. h->all.pbrd[i]->chs = info.chs;
  462. h->all.pbrd[i]->addr = i;
  463. h->all.pbrd[i]->pch = (power_ch_t*)calloc(1, sizeof(power_ch_t)*info.chs);
  464. if(h->all.pbrd[i]->pch) {
  465. for(j=0; j<info.chs; j++) {
  466. h->all.pbrd[i]->pch[j].info.addr = i;
  467. h->all.pbrd[i]->pch[j].info.ch = idx; //序号程序从0开始
  468. h->all.pbrd[i]->pch[j].info.sch = j; //序号从0开始
  469. h->all.pbrd[i]->pch[j].info.pid = i;
  470. h->all.pbrd[i]->pch[j].info.addr = i;
  471. idx++;
  472. }
  473. }
  474. }
  475. chs += info.chs;
  476. }
  477. }
  478. if(chs>0) {
  479. idx = 0;
  480. h->all.chs = 0;
  481. h->all.pch = (power_ch_t**)calloc(1, sizeof(power_ch_t*)*chs);
  482. if(h->all.pch) {
  483. h->all.chs = chs;
  484. for(i=1; i<=max_addr; i++) {
  485. board_data_t *pbrd=h->all.pbrd[i];
  486. for(j=0; j<pbrd->chs; j++) {
  487. h->all.pch[idx++] = &h->all.pbrd[i]->pch[j];
  488. }
  489. }
  490. }
  491. }
  492. lock_d_release(h->lck);
  493. LOGD("___ power scan end\n");
  494. return 0;
  495. }
  496. int power_clear(void)
  497. {
  498. int i,j;
  499. cboard_handle_t *h=&cbHandle;
  500. lock_d_hold(h->lck);
  501. for(i=0; i<BRD_MAX; i++) {
  502. if(h->all.pbrd[i]) {
  503. for(j=0; j<h->all.pbrd[i]->chs; j++) {
  504. if(h->all.pbrd[i]->pch) {
  505. free(h->all.pbrd[i]->pch);
  506. h->all.pbrd[i]->pch = NULL;
  507. }
  508. h->all.pbrd[i]->chs = 0;
  509. }
  510. free(h->all.pbrd[i]);
  511. h->all.pbrd[i] = NULL;
  512. }
  513. h->all.cnt = 0;
  514. }
  515. lock_d_release(h->lck);
  516. return 0;
  517. }
  518. int power_reset(int addr)
  519. {
  520. int i,r=-1;
  521. uint16_t offset = 0;
  522. cboard_handle_t *h=&cbHandle;
  523. board_data_t *pb=NULL;
  524. if(addr>BRD_MAX) {
  525. return -1;
  526. }
  527. pb = h->all.pbrd[addr];
  528. if(!pb) {
  529. return -1;
  530. }
  531. switch(pb->type) {
  532. case AC_SINGLE_S_TYPE:
  533. case AC_SINGLE_B_TYPE:
  534. {
  535. uint16_t tmp[8];
  536. offset = POWER_AC_CH_STAT_L;
  537. for(i=0; i<pb->chs; i++) {
  538. tmp[i] = pb->pch[i].power[0].status;
  539. }
  540. r = write_reg(h, pb->addr, offset, tmp, pb->chs);
  541. }
  542. break;
  543. case DCPDU_TYPE:
  544. {
  545. offset = POWER_DC_ALARM_CTRL_TOTAL;
  546. }
  547. break;
  548. case TREE_AC_TYPE:
  549. {
  550. uint16_t data_temp[20];
  551. offset = POWER_AC3_RESET_CONSUMP;
  552. data_temp[0] = data_temp[1] = data_temp[2] = 1;
  553. r = write_reg(h, pb->addr, offset, data_temp, 3);
  554. if (r<0) {
  555. return r;
  556. }
  557. //初始化报警阈值
  558. uint32_t value = 0;
  559. memset(data_temp, 0, sizeof(data_temp));
  560. offset = POWER_AC3_THRESHOLD_VOL_MAX;
  561. r = write_reg(h, pb->addr, offset, data_temp, 18);
  562. if (r<0) {
  563. return r;
  564. }
  565. offset = POWER_AC3_THRESHOLD_VOL_MIN;
  566. r = write_reg(h, pb->addr, offset, data_temp, 18);
  567. if (r<0) {
  568. return r;
  569. }
  570. offset = POWER_AC3_THRESHOLD_CUR_MAX;
  571. r = write_reg(h, pb->addr, offset, data_temp, 18);
  572. if (r<0) {
  573. return r;
  574. }
  575. offset = POWER_AC3_THRESHOLD_PWR_MAX;
  576. r = write_reg(h, pb->addr, offset, data_temp, 18);
  577. if (r<0) {
  578. return r;
  579. }
  580. offset = POWER_AC3_THRESHOLD_PWRCON_MAX;
  581. r = write_reg(h, pb->addr, offset, data_temp, 18);
  582. if (r<0) {
  583. return r;
  584. }
  585. for (i = 0; i < pb->chs; i++) {
  586. memset(data_temp, 0, sizeof(data_temp));
  587. offset = POWER_AC3_OUT_ENABLE + i;
  588. data_temp[0] = pb->pch[i].power[0].status;
  589. r = write_reg(h, pb->addr, offset, data_temp, 2);
  590. if (r<0) {
  591. return r;
  592. }
  593. }
  594. }
  595. break;
  596. default:
  597. return -1;
  598. }
  599. return 0;
  600. }
  601. int power_set_sw(int ch, int on)
  602. {
  603. int r;
  604. power_ch_t pc;
  605. uint16_t offset=0,data_temp[2];
  606. cboard_handle_t *h=&cbHandle;
  607. r = get_ch(h, ch, &pc);
  608. if(r) {
  609. return -1;
  610. }
  611. switch(pc.info.type) {
  612. case AC_SINGLE_S_TYPE:
  613. case AC_SINGLE_B_TYPE:
  614. {
  615. offset = POWER_AC_CH_STAT_L + ch;
  616. data_temp[0] = on; data_temp[1] = 0;
  617. }
  618. break;
  619. case DCPDU_TYPE:
  620. {
  621. offset = POWER_DC_SET_STAT + ch;
  622. data_temp[0] = on; data_temp[1] = 0;
  623. }
  624. break;
  625. case TREE_AC_TYPE:
  626. {
  627. if(ch<0) {//##################################
  628. //offset = POWER_AC3_OUT_INFO + ch;
  629. //data_temp[0] = on; data_temp[1] = 0;
  630. }
  631. }
  632. break;
  633. default:
  634. return -1;
  635. }
  636. data_temp[0] = on; data_temp[1] = 0;
  637. r = write_reg(h, pc.info.addr, offset, data_temp, 2);
  638. return r;
  639. }
  640. int power_set_alarm(int ch, alarm_t *alarm)
  641. {
  642. int r=-1;
  643. power_ch_t pc;
  644. uint16_t offset = 0;
  645. uint16_t nStatus = 0;
  646. cboard_handle_t *h=&cbHandle;
  647. r = get_ch(h, ch, &pc);
  648. if(r) {
  649. return -1;
  650. }
  651. switch(pc.info.type) {
  652. case AC_SINGLE_S_TYPE:
  653. case AC_SINGLE_B_TYPE:
  654. {
  655. if (ch == -1) {
  656. offset = POWER_AC_ALARM_CTRL_TOTAL;
  657. }
  658. else {
  659. offset = POWER_AC_ALARM_CTRL + ch;
  660. }
  661. }
  662. break;
  663. case DCPDU_TYPE:
  664. {
  665. if (ch == -1) {
  666. offset = POWER_DC_ALARM_CTRL_TOTAL;
  667. }
  668. else {
  669. offset = POWER_DC_ALARM_CTRL + ch;
  670. }
  671. }
  672. break;
  673. case TREE_AC_TYPE:
  674. {
  675. if (ch == -1) {
  676. offset = POWER_AC3_ALARM_CTRL_TOTAL;
  677. }
  678. else {
  679. offset = POWER_AC3_ALARM_CTRL + ch;
  680. }
  681. }
  682. break;
  683. default:
  684. return -1;
  685. }
  686. if(pc.thr.v_upper.act==1) nStatus |= BIT(1);
  687. if(pc.thr.v_lower.act==1) nStatus |= BIT(2);
  688. if(pc.thr.c_upper.act==1) nStatus |= BIT(0);
  689. if(pc.thr.p_upper.act==1) nStatus |= BIT(3);
  690. if(pc.thr.w_upper.act==1) nStatus |= BIT(4);
  691. r = write_reg(h, pc.info.addr, offset, &nStatus, 1);
  692. return r;
  693. }
  694. int power_set_thr(int ch, thr_t *thr)
  695. {
  696. int r=-1;
  697. power_ch_t pc;
  698. uint16_t offset;
  699. cboard_handle_t *h=&cbHandle;
  700. r = get_ch(h, ch, &pc);
  701. if(r) {
  702. return -1;
  703. }
  704. switch(pc.info.type) {
  705. case AC_SINGLE_S_TYPE:
  706. case AC_SINGLE_B_TYPE:
  707. {
  708. uint16_t offset = 0;
  709. uint32_t data_temp = 0 ;
  710. uint16_t data_buf[16] = {0};
  711. //电压上限
  712. data_temp = (thr->v_upper.val*1000);
  713. data_buf[0] = data_temp;
  714. data_buf[1] = data_temp>>16;
  715. //电压下限
  716. data_temp = (thr->v_upper.val*1000);
  717. data_buf[2] = data_temp;
  718. data_buf[3] = data_temp>>16;
  719. //电流上限
  720. data_temp = (thr->v_upper.val*1000);
  721. data_buf[4] = data_temp;
  722. data_buf[5] = data_temp>>16;
  723. //电流下限
  724. data_temp = (0);
  725. data_buf[6] = data_temp;
  726. data_buf[7] = data_temp>>16;
  727. //功率上限
  728. data_temp = (thr->v_upper.val*1000);
  729. data_buf[8] = data_temp;
  730. data_buf[9] = data_temp>>16;
  731. //功率下限
  732. data_temp = 0;
  733. data_buf[10] = data_temp;
  734. data_buf[11] = data_temp>>16;
  735. //电能上限
  736. data_temp = (thr->v_upper.val*1000);
  737. data_buf[12] = data_temp;
  738. data_buf[13] = data_temp>>16;
  739. //电能下限
  740. data_temp = 0;
  741. data_buf[14] = data_temp;
  742. data_buf[15] = data_temp>>16;
  743. if(ch<0) {
  744. offset = POWER_AC_TOTAL_THRESHOLD;
  745. }
  746. else {
  747. offset = POWER_AC_THRESHOLD_L+ch*16;
  748. }
  749. r = write_reg(h, pc.info.addr, offset, data_buf, 16);
  750. //power_set_alarm();
  751. }
  752. break;
  753. case DCPDU_TYPE:
  754. {
  755. uint16_t data_temp[4];
  756. uint32_t value;
  757. offset = (ch<0)?POWER_DC_THRESHOLD_TOTAL_VOL_MAX:POWER_DC_THRESHOLD_VOL_MAX;
  758. value = thr->v_upper.val * 1000;
  759. data_temp[0] = value & 0XFFFF;
  760. data_temp[1] = (value >> 16) & 0xFFFF;
  761. r = write_reg(h, pc.info.addr, offset, data_temp, 2);
  762. offset = (ch<0)?POWER_DC_THRESHOLD_TOTAL_VOL_MIN:POWER_DC_THRESHOLD_VOL_MIN;
  763. value = thr->v_lower.val * 1000;
  764. data_temp[0] = value & 0XFFFF;
  765. data_temp[1] = (value >> 16) & 0xFFFF;
  766. r = write_reg(h, pc.info.addr, offset, data_temp, 2);
  767. offset = (ch<0)?POWER_DC_THRESHOLD_TOTAL_CUR_MAX:POWER_DC_THRESHOLD_CUR_MAX;
  768. value = thr->c_upper.val * 1000;
  769. data_temp[0] = value & 0XFFFF;
  770. data_temp[1] = (value >> 16) & 0xFFFF;
  771. r = write_reg(h, pc.info.addr, offset, data_temp, 2);
  772. offset = (ch<0)?POWER_DC_THRESHOLD_TOTAL_PWR_MAX:POWER_DC_THRESHOLD_POWER_MAX;
  773. value = thr->p_upper.val * 1000;
  774. data_temp[0] = value & 0XFFFF;
  775. data_temp[1] = (value >> 16) & 0xFFFF;
  776. r = write_reg(h, pc.info.addr, offset, data_temp, 2);
  777. offset = (ch<0)?POWER_DC_THRESHOLD_TOTAL_PWRCON_MAX:POWER_DC_THRESHOLD_POWERCON_MAX;
  778. value = thr->w_upper.val * 1000;
  779. data_temp[0] = value & 0XFFFF;
  780. data_temp[1] = (value >> 16) & 0xFFFF;
  781. r = write_reg(h, pc.info.addr, offset, data_temp, 2);
  782. //power_set_alarm();
  783. }
  784. break;
  785. case TREE_AC_TYPE:
  786. {
  787. uint16_t data_temp[4];
  788. uint32_t value;
  789. if(ch<0) {
  790. offset = POWER_AC3_THRESHOLD_IN;
  791. value = thr->v_upper.val * 1000;
  792. data_temp[0] = value & 0XFFFF;
  793. data_temp[1] = (value >> 16) & 0xFFFF;
  794. r = write_reg(h, pc.info.addr, offset, data_temp, 2);
  795. value = thr->v_upper.val * 1000;
  796. data_temp[0] = value & 0XFFFF;
  797. data_temp[1] = (value >> 16) & 0xFFFF;
  798. r = write_reg(h, pc.info.addr, offset+1, data_temp, 2);
  799. value = thr->c_upper.val * 1000;
  800. data_temp[0] = value & 0XFFFF;
  801. data_temp[1] = (value >> 16) & 0xFFFF;
  802. r = write_reg(h, pc.info.addr, offset+2, data_temp, 2);
  803. value = thr->p_upper.val * 1000;
  804. data_temp[0] = value & 0XFFFF;
  805. data_temp[1] = (value >> 16) & 0xFFFF;
  806. r = write_reg(h, pc.info.addr, offset+3, data_temp, 2);
  807. value = thr->w_upper.val * 1000;
  808. data_temp[0] = value & 0XFFFF;
  809. data_temp[1] = (value >> 16) & 0xFFFF;
  810. r = write_reg(h, pc.info.addr, offset+4, data_temp, 2);
  811. }
  812. else {
  813. offset = POWER_AC3_THRESHOLD_VOL_MAX;
  814. value = thr->v_upper.val * 1000;
  815. data_temp[0] = value & 0XFFFF;
  816. data_temp[1] = (value >> 16) & 0xFFFF;
  817. r = write_reg(h, pc.info.addr, offset, data_temp, 2);
  818. offset = POWER_AC3_THRESHOLD_VOL_MIN;
  819. value = thr->v_lower.val * 1000;
  820. data_temp[0] = value & 0XFFFF;
  821. data_temp[1] = (value >> 16) & 0xFFFF;
  822. r = write_reg(h, pc.info.addr, offset, data_temp, 2);
  823. offset = POWER_AC3_THRESHOLD_CUR_MAX;
  824. value = thr->c_upper.val * 1000;
  825. data_temp[0] = value & 0XFFFF;
  826. data_temp[1] = (value >> 16) & 0xFFFF;
  827. r = write_reg(h, pc.info.addr, offset, data_temp, 2);
  828. offset = POWER_AC3_THRESHOLD_PWR_MAX;
  829. value = thr->p_upper.val * 1000;
  830. data_temp[0] = value & 0XFFFF;
  831. data_temp[1] = (value >> 16) & 0xFFFF;
  832. r = write_reg(h, pc.info.addr, offset, data_temp, 2);
  833. offset = POWER_AC3_THRESHOLD_VOL_MAX;
  834. value = thr->w_upper.val * 1000;
  835. data_temp[0] = value & 0XFFFF;
  836. data_temp[1] = (value >> 16) & 0xFFFF;
  837. r = write_reg(h, pc.info.addr, offset, data_temp, 2);
  838. }
  839. }
  840. break;
  841. }
  842. return r;
  843. }
  844. ///////////////////////////////////////////////////////
  845. static board_fn_t board_dc_fn={
  846. //
  847. };
  848. static board_fn_t board_ac_fn={
  849. //
  850. };
  851. static board_fn_t board_ac3_fn={
  852. //
  853. };
  854. int cboard_init(void)
  855. {
  856. cboard_handle_t *h=&cbHandle;
  857. mb_para_t para={
  858. .mode = MB_MODE_MASTER,
  859. .type = MB_TYPE_RTU,
  860. .para = {
  861. .rtu = {
  862. .dev = POWER_PORT, //设备名
  863. .baudrate = 115200, //波特率
  864. .parity = 0, //校验位
  865. .pin = 1, //收发控制引脚, <0 表示不使用
  866. .lvl = 0, //发送控制电平
  867. }
  868. }
  869. };
  870. memset(h, 0, sizeof(cboard_handle_t));
  871. h->lck = lock_d_init();
  872. h->mb = mb_init(&para);
  873. if(!h->mb) {
  874. return -1;
  875. }
  876. }