power.c 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470
  1. #include "mb.h"
  2. #include "cfg.h"
  3. #include "web.h"
  4. #include "lock.h"
  5. #include "list.h"
  6. #include "paras.h"
  7. #include "power.h"
  8. #include "thread.h"
  9. #include "datadef.h"
  10. #define BRD_NUM 3 //BRD_MAX
  11. #define BRD_TIMEOUT 200
  12. #define RETRY_TIMES 3
  13. #define LIMIT_HOF(x) (x*1.1f)
  14. #define LIMIT_LOF(x) (x*0.9f)
  15. typedef struct {
  16. void* mb;
  17. lock_t lck;
  18. uint8_t cur_addr;
  19. uint8_t chs; //所有控制板的总通道数
  20. power_ch_t **pch; //动态指针
  21. power_ch_t ch0;
  22. uint8_t cnt; //实际扫到的板子个数,不可大于BRD_MAX
  23. uint8_t brd_max;
  24. board_data_t *pbrd[BRD_MAX+1]; //通过modbus地址索引
  25. board_key_t key[BRD_MAX+1];
  26. power_total_t ttl;
  27. product_data_t *prod;
  28. power_data_t pdat;
  29. }power_handle_t;
  30. static board_fn_t board_fn={
  31. .get_power = NULL,
  32. .get_alarm = NULL,
  33. .set_ch = NULL,
  34. .set_open_delay = NULL,
  35. .set_close_delay = NULL,
  36. .set_kb_value = NULL,
  37. .set_threshold = NULL,
  38. .reset_consump = NULL,
  39. .detect = NULL,
  40. .get_info = NULL,
  41. //.get_board = NULL,
  42. .set_all = NULL,
  43. };
  44. static power_handle_t pwrHandle={0};
  45. static int alarm_evt_handle(power_handle_t *h, power_ch_t *pch, uint32_t flag)
  46. {
  47. alarm_data_t ad;
  48. ad.ch = pch->info.ch;
  49. ad.alarm = pch->alarm;
  50. ad.time = pch->time;
  51. web_post(PKT_TYPE_ALARM, &ad, sizeof(ad));
  52. return 0;
  53. }
  54. static void memswap(uint8_t *buf, int len)
  55. {
  56. int i;
  57. uint8_t tmp;
  58. for(i=0; i<len; i+=2) {
  59. tmp = buf[i];
  60. buf[i] = buf[i+1];
  61. buf[i+1] = tmp;
  62. }
  63. }
  64. static int read_reg(power_handle_t *h, uint8_t addr, uint16_t reg, uint16_t *data, int cnt)
  65. {
  66. int i,r;
  67. for(i=0; i<RETRY_TIMES; i++) {
  68. r = mb_read(h->mb, addr, reg, data, cnt, BRD_TIMEOUT);
  69. if(r==0) break;
  70. }
  71. return r;
  72. }
  73. static int write_reg(power_handle_t *h, uint8_t addr, uint16_t reg, uint16_t *data, int cnt)
  74. {
  75. int i,r;
  76. for(i=0; i<RETRY_TIMES; i++) {
  77. r = mb_write(h->mb, addr, reg, data, cnt);
  78. if(r==0) break;
  79. }
  80. return r;
  81. }
  82. ////////////////////////////////////////////////////////////////////
  83. static int get_key(power_handle_t *h, uint8_t addr, board_key_t *key)
  84. {
  85. int i,r=-1;
  86. uint16_t tmp[2];
  87. if(h->prod->pwr_type==PDU_AC_I1O1 || h->prod->pwr_type==PDU_AC_I3O1_H) {
  88. r = read_reg(h, addr, POWER_AC_GET_INFO, tmp, 1);
  89. if(r==0) {
  90. key->type = (tmp[0]>>8)&0xFF;
  91. key->chs = tmp[0]&0xFF;
  92. }
  93. }
  94. else {
  95. r = read_reg(h, addr, POWER_DC_INFO, tmp, 2);
  96. if(r==0) {
  97. key->type = (tmp[0]>>8)&0xFF;
  98. key->chs = tmp[0]&0xFF;
  99. return 0;
  100. }
  101. }
  102. return r;
  103. }
  104. ////////////////////////////////////////////////////////////////
  105. static int set_kb_value(power_handle_t *h, int type, int addr, kb_val_t *kv)
  106. {
  107. switch(type) {
  108. case AC_SINGLE_S_TYPE:
  109. {
  110. /*
  111. unsigned int offset = 0;
  112. unsigned int rval = 0 ;
  113. unsigned short data_temp[8] = {0};
  114. if(chn>=8)
  115. return -1;
  116. offset = _SWITCH_AC_SINGLE_S_KB_VAL+chn*8;
  117. data_temp[0] = (unsigned short)_kb_val->voltage_k;
  118. data_temp[1] = (unsigned short)((_kb_val->voltage_k-data_temp[0])*1000);
  119. data_temp[2] = (unsigned short)_kb_val->voltage_b;
  120. data_temp[3] = (unsigned short)((_kb_val->voltage_b-data_temp[2])*1000);
  121. data_temp[4] = (unsigned short)_kb_val->current_k;
  122. data_temp[5] = (unsigned short)((_kb_val->current_k-data_temp[4])*1000);
  123. data_temp[6] = (unsigned short)_kb_val->current_b;
  124. data_temp[7] = (unsigned short)((_kb_val->current_b-data_temp[6])*1000);
  125. g_modbus_write_x_reg(manger,saddr,offset,8,data_temp);
  126. */
  127. }
  128. break;
  129. case AC_SINGLE_B_TYPE:
  130. {
  131. /*
  132. unsigned int offset = 0;
  133. unsigned int rval = 0 ;
  134. unsigned short data_temp[8] = {0};
  135. if(pch->info.>=4)
  136. return -1;
  137. offset = _SWITCH_AC_SINGLE_B_KB_VAL+chn*8;
  138. data_temp[0] = (unsigned short)_kb_val->voltage_k;
  139. data_temp[1] = (unsigned short)((_kb_val->voltage_k-data_temp[0])*1000);
  140. data_temp[2] = (unsigned short)_kb_val->voltage_b;
  141. data_temp[3] = (unsigned short)((_kb_val->voltage_b-data_temp[2])*1000);
  142. data_temp[4] = (unsigned short)_kb_val->current_k;
  143. data_temp[5] = (unsigned short)((_kb_val->current_k-data_temp[4])*1000);
  144. data_temp[6] = (unsigned short)_kb_val->current_b;
  145. data_temp[7] = (unsigned short)((_kb_val->current_b-data_temp[6])*1000);
  146. g_modbus_write_x_reg(manger,saddr,offset,8,data_temp);
  147. */
  148. }
  149. break;
  150. case DCPDU_TYPE:
  151. {/*
  152. unsigned short offset = 0;
  153. unsigned short data_temp[8] = {0};
  154. offset = _SWITCH_DC_KB_VAL;
  155. data_temp[0] = (unsigned short)_kb_val->voltage_k;
  156. data_temp[1] = (unsigned short)((_kb_val->voltage_k-data_temp[0])*1000);
  157. data_temp[2] = (unsigned short)_kb_val->voltage_b;
  158. data_temp[3] = (unsigned short)((_kb_val->voltage_b-data_temp[2])*1000);
  159. data_temp[4] = (unsigned short)_kb_val->current_k;
  160. data_temp[5] = (unsigned short)((_kb_val->current_k-data_temp[4])*1000);
  161. data_temp[6] = (unsigned short)_kb_val->current_b;
  162. data_temp[7] = (unsigned short)((_kb_val->current_b-data_temp[6])*1000);
  163. g_modbus_write_x_reg(manger,saddr,offset,8, data_temp);
  164. */
  165. }
  166. break;
  167. case TREE_AC_TYPE:
  168. {
  169. }
  170. break;
  171. case AC_MULTI_S_TYPE:
  172. case AC_MULTI_B_TYPE:
  173. case DC_OUT_TYPE:
  174. case DC_IN_TYPE:
  175. default:
  176. return -1;
  177. }
  178. }
  179. static int reset_consump(power_handle_t *h, int type, int addr)
  180. {
  181. switch(type) {
  182. case AC_SINGLE_S_TYPE:
  183. case AC_SINGLE_B_TYPE:
  184. {
  185. }
  186. break;
  187. case DCPDU_TYPE:
  188. {
  189. }
  190. break;
  191. case TREE_AC_TYPE:
  192. {
  193. }
  194. break;
  195. case AC_MULTI_S_TYPE:
  196. case AC_MULTI_B_TYPE:
  197. case DC_OUT_TYPE:
  198. case DC_IN_TYPE:
  199. default:
  200. return -1;
  201. }
  202. }
  203. //////////////////////////////////////////////////////////////////
  204. static uint8_t get_ch_idx(board_data_t *pbrd, uint8_t sch)
  205. {
  206. uint8_t ch=0;
  207. uint8_t pwr_type=paras_get()->prod.pwr_type;
  208. if(pbrd->type==TREE_AC_TYPE) {
  209. if(pwr_type == PDU_AC_I3O3) {
  210. ch = pbrd->ch0 + sch/3;
  211. }
  212. else {
  213. ch = pbrd->ch0 + sch;
  214. }
  215. }
  216. else {
  217. ch = pbrd->ch0 + sch;
  218. }
  219. return ch;
  220. }
  221. static int threshold_proc(power_handle_t *h, board_data_t *pbrd)
  222. {
  223. int i,j,r=-1,times=1;
  224. power_ch_t *pch=NULL;
  225. for (i=0; i<pbrd->chs; i++) {
  226. pch = &pbrd->pch[i];
  227. if(h->prod->pwr_type==PDU_AC_I3O3) {
  228. times = 3;
  229. //设置为输出三相且三相有缺失则报警
  230. if(pch->info.ph_val && pbrd->ph_loss) {
  231. alarm_evt_handle(h, pch, THRESHOLD_V_UPPER);
  232. }
  233. }
  234. for(j=0; j<times; j++) {
  235. if(pch->thr.v_upper.en) {
  236. if(pch->power[j].voltage>pch->thr.v_upper.val) {
  237. if(pch->alarm.v_upper==0) {
  238. pch->alarm.v_upper = 1;
  239. alarm_evt_handle(h, pch, THRESHOLD_V_UPPER);
  240. }
  241. }
  242. else if(pch->power[j].voltage<pch->thr.v_lower.val) {
  243. if(pch->alarm.v_lower==0) {
  244. pch->alarm.v_lower = 1;
  245. alarm_evt_handle(h, pch, THRESHOLD_V_LOWER);
  246. }
  247. }
  248. else {
  249. pch->alarm.v_upper = 0;
  250. pch->alarm.v_lower = 0;
  251. }
  252. }
  253. if(pch->thr.c_upper.en) {
  254. if(pch->power[j].current>pch->thr.c_upper.val) {
  255. if(pch->alarm.c_upper==0) {
  256. pch->alarm.c_upper = 1;
  257. alarm_evt_handle(h, pch, THRESHOLD_C_UPPER);
  258. }
  259. }
  260. else {
  261. pch->alarm.c_upper = 0;
  262. }
  263. }
  264. if(pch->thr.p_upper.en) {
  265. if(pch->power[j].power>pch->thr.p_upper.val) {
  266. if(pch->alarm.p_upper==0) {
  267. pch->alarm.p_upper = 1;
  268. alarm_evt_handle(h, pch, THRESHOLD_P_UPPER);
  269. }
  270. }
  271. else {
  272. pch->alarm.p_upper = 0;
  273. }
  274. }
  275. if(pch->thr.w_upper.en) {
  276. if(pch->power[j].current>pch->thr.w_upper.val) {
  277. if(pch->alarm.w_upper==0) {
  278. pch->alarm.w_upper = 1;
  279. alarm_evt_handle(h, pch, THRESHOLD_W_UPPER);
  280. }
  281. }
  282. else {
  283. pch->alarm.w_upper = 0;
  284. }
  285. }
  286. }
  287. }
  288. return 0;
  289. }
  290. static int total_proc(power_handle_t *h)
  291. {
  292. total_t tmp[3]={0};
  293. int i,j,k,r=-1,times=1;
  294. power_ch_t *pch=NULL;
  295. board_data_t *pbrd=NULL;
  296. lock_on(h->lck);
  297. if(h->prod->pwr_type==PDU_AC_I3O3) times = 3;
  298. for(i=0; i<h->brd_max; i++) {
  299. if(h->pbrd[i]) {
  300. for (j=0; i<h->pbrd[i]->chs; i++) {
  301. pch = &h->pbrd[i]->pch[j];
  302. for(k=0; k<times; k++) {
  303. tmp[k].voltage = pch->power[j].voltage;
  304. tmp[k].current += pch->power[j].current;
  305. tmp[k].power += pch->power[j].power;
  306. tmp[k].freq = pch->power[j].freq;
  307. tmp[k].consump += pch->power[j].consump;
  308. tmp[k].active = pch->power[j].active;
  309. tmp[k].reactive = pch->power[j].reactive;
  310. }
  311. }
  312. }
  313. }
  314. h->ttl.type = h->prod->pwr_type;
  315. for(k=0; k<times; k++) {
  316. h->ttl.total[k].voltage = tmp[k].voltage;
  317. h->ttl.total[k].current = tmp[k].current;
  318. h->ttl.total[k].power = tmp[k].power;
  319. h->ttl.total[k].freq = tmp[k].freq;
  320. h->ttl.total[k].consump = tmp[k].consump;
  321. h->ttl.total[k].factor = tmp[k].active/tmp[k].power;
  322. h->ttl.total[k].active = tmp[k].active;
  323. h->ttl.total[k].reactive = tmp[k].reactive;
  324. }
  325. lock_off(h->lck);
  326. return 0;
  327. }
  328. static int board_read(power_handle_t *h, board_data_t *pbrd)
  329. {
  330. int i,j,r=-1;
  331. power_t *pwr,power;
  332. uint16_t offset,tmp[144];
  333. power_ch_t *pch=NULL;
  334. lock_on(h->lck);
  335. if(pbrd) {
  336. time_t tm = mktime(localtime(NULL));
  337. switch(pbrd->type) {
  338. case AC_SINGLE_S_TYPE:
  339. case AC_SINGLE_B_TYPE:
  340. {
  341. uint32_t val;
  342. offset = POWER_AC_CUR_INFO_L;
  343. r = read_reg(h, pbrd->addr, offset, tmp, pbrd->chs*12);
  344. if (r<0) {
  345. LOGE("read_reg failed, addr:%d reg:0x%04x/%d cnt:%d\n", pbrd->addr, offset, offset, pbrd->chs*12);
  346. break;
  347. }
  348. for (i=0; i<pbrd->chs; i++) {
  349. int idx = i * 12;
  350. pwr = &pbrd->pch[i].power[0];
  351. val = (tmp[1 + idx] << 16) | tmp[0 + idx];
  352. pwr->voltage = val / 1000.0;
  353. val = (tmp[3 + idx] << 16) | tmp[2 + idx];
  354. pwr->current = val / 1000.0;
  355. val = (tmp[5 + idx] << 16) | tmp[4 + idx];
  356. pwr->power = val / 1000.0;
  357. val = (tmp[7 + idx] << 16) | tmp[6 + idx];
  358. pwr->freq = val / 1000.0;
  359. val = (tmp[9 + idx] << 16) | tmp[8 + idx];
  360. pwr->consump = val / 1000.0;
  361. val = (tmp[11 + idx] << 16) | tmp[10 + idx];
  362. pwr->factor = val / 1000.0;
  363. pbrd->pch[i].time = tm;
  364. }
  365. offset = POWER_AC_STAT_INFO_L;
  366. r = read_reg(h, pbrd->addr, offset, tmp, pbrd->chs);
  367. if (r<0) {
  368. LOGE("read_reg failed, addr:%d reg:0x%04x/%d cnt:%d\n", pbrd->addr, offset, offset, pbrd->chs);
  369. break;
  370. }
  371. for (i=0; i<pbrd->chs; i++) {
  372. pch = &pbrd->pch[i];
  373. pch->power[0].status = tmp[i] & (0x01);
  374. pch->alarm.v_upper = tmp[i] & ALARM_V_UPPER;
  375. pch->alarm.v_lower = tmp[i] & ALARM_V_LOWER;
  376. pch->alarm.c_upper = tmp[i] & ALARM_C_UPPER;
  377. pch->alarm.p_upper = tmp[i] & ALARM_P_UPPER;
  378. pch->alarm.w_upper = tmp[i] & ALARM_W_UPPER;
  379. pch->alarm.ph_loss = 0;
  380. }
  381. }
  382. break;
  383. case DCPDU_TYPE:
  384. {
  385. uint32_t flag;
  386. uint16_t *ptmp = tmp + 32;
  387. offset = POWER_DC_OUT_INFO + 16;
  388. r = read_reg(h, pbrd->addr, offset, ptmp, 32);
  389. if (r<0) {
  390. LOGE("read_reg failed, addr:%d reg:0x%04x/%d cnt:%d\n", pbrd->addr, offset, offset, 32);
  391. break;
  392. }
  393. for (i = 0; i < pbrd->chs; i++) {
  394. int Index = i * 8;
  395. pwr = &pbrd->pch[i].power[0];
  396. float value = (tmp[1 + Index] << 16) + tmp[0 + Index];
  397. pwr->voltage = value / 1000.0;
  398. value = (tmp[3 + Index] << 16) + tmp[2 + Index];
  399. pwr->current = value / 1000.0;
  400. value = (tmp[5 + Index] << 16) + tmp[4 + Index];
  401. pwr->power = value / 1000.0;
  402. value = (tmp[7 + Index] << 16) + tmp[6 + Index];
  403. pwr->consump = value / 1000.0;
  404. pwr->freq = 0;
  405. pwr->factor = 1;
  406. pbrd->pch[i].time = tm;
  407. }
  408. offset = POWER_DC_STAT_INFO;
  409. r = read_reg(h, pbrd->addr, offset, tmp, 2);
  410. if (r<0) {
  411. LOGE("read_reg failed, addr:%d reg:0x%04x/%d cnt:%d\n", pbrd->addr, offset, offset, 2);
  412. break;
  413. }
  414. for (i = 0; i < pbrd->chs; i++) {
  415. flag = (tmp[1] << 16) + tmp[0];
  416. pbrd->pch[i].power[0].status = (flag >> i) & 0x1;
  417. }
  418. // 获取报警状态
  419. offset = POWER_DC_WARNING;
  420. r = read_reg(h, pbrd->addr, offset, tmp, 16);
  421. if (r<0) {
  422. LOGE("read_reg failed, addr:%d reg:0x%04x/%d cnt:%d\n", pbrd->addr, offset, offset, 16);
  423. break;
  424. }
  425. for (i = 0; i < pbrd->chs; i++) {
  426. int Index = i * 2;
  427. pch = &pbrd->pch[i];
  428. pch->alarm.v_upper = tmp[0+Index] & BIT(0);
  429. pch->alarm.v_lower = tmp[0+Index] & BIT(1);
  430. pch->alarm.c_upper = tmp[0+Index] & BIT(2);
  431. pch->alarm.p_upper = tmp[0+Index] & BIT(3);
  432. pch->alarm.w_upper = tmp[0+Index] & BIT(4);
  433. }
  434. }
  435. break;
  436. case TREE_AC_TYPE:
  437. {
  438. uint8_t v=0;
  439. offset = POWER_AC3_OUT_INFO;
  440. r = read_reg(h, pbrd->addr, offset, tmp, 80);
  441. if (r < 0) {
  442. LOGE("read_reg failed, addr:%d reg:0x%04x/%d cnt:%d\n", pbrd->addr, offset, offset, 80);
  443. break;
  444. }
  445. offset = POWER_AC3_OUT_INFO+40;
  446. uint16_t* ptmp=tmp+80;
  447. r = read_reg(h, pbrd->addr, offset, ptmp, 64);
  448. if (r < 0) {
  449. LOGE("read_reg failed, addr:%d reg:0x%04x/%d cnt:%d\n", pbrd->addr, offset, offset, 64);
  450. break;
  451. }
  452. for (i=0; i<pbrd->chs; i++) {
  453. int Index = i * 16;
  454. if(h->prod->pwr_type==PDU_AC_I3O3) {
  455. int ch_idx = pbrd->ch0+i/3;
  456. int ph_idx = i%3;
  457. pwr = &pbrd->pch[ch_idx].power[ph_idx];
  458. }
  459. else {
  460. pwr = &pbrd->pch[i].power[0];
  461. }
  462. float value = (tmp[1+Index] << 16) + tmp[0+Index];
  463. pwr->voltage = value / 1000.0f;
  464. value = (tmp[3+Index] << 16) + tmp[2+Index];
  465. pwr->current = value / 1000.0f;
  466. value = (tmp[5+Index] << 16) + tmp[4+Index];
  467. pwr->power = value / 1000.0f;
  468. value = (tmp[7+Index] << 16) + tmp[6+Index];
  469. value = (tmp[9+Index] << 16) + tmp[8+Index];
  470. value = (tmp[11+Index] << 16) + tmp[10+Index];
  471. pwr->freq = value / 1000.0f;
  472. value = (tmp[13+Index] << 16) + tmp[12+Index];
  473. pwr->consump = value / 1000.0f;
  474. value = (tmp[15+Index] << 16) + tmp[14+Index];
  475. pwr->factor = value / 1023.0f;
  476. pbrd->pch[i].time = tm;
  477. }
  478. //获取通道开关状态及零线状态
  479. offset = POWER_AC3_OUT_ENABLE;
  480. r = read_reg(h, pbrd->addr, offset, tmp, 20);
  481. if (r < 0) {
  482. LOGE("read_reg failed, addr:%d reg:0x%04x/%d cnt:%d\n", pbrd->addr, offset, offset, 20);
  483. break;
  484. }
  485. for (i=0; i<pbrd->chs; i++) {
  486. int Index = i * 2;
  487. pbrd->pch[i].power[0].status = tmp[0+Index] & 0x01;
  488. pbrd->pch[i].power[0].nwire = tmp[18] & 0x01;
  489. }
  490. //获取故障状态
  491. offset = POWER_AC3_OUT_ERROR;
  492. r = read_reg(h, pbrd->addr, offset, tmp, 18);
  493. if (r < 0) {
  494. LOGE("read_reg failed, addr:%d reg:0x%04x/%d cnt:%d\n", pbrd->addr, offset, offset, 18);
  495. break;
  496. }
  497. for (i=0; i<pbrd->chs; i++) {
  498. int Index = i * 2;
  499. pch = &pbrd->pch[i];
  500. pch->alarm.v_upper = tmp[0+Index] & BIT(0);
  501. pch->alarm.v_lower = tmp[0+Index] & BIT(1);
  502. pch->alarm.c_upper = tmp[0+Index] & BIT(2);
  503. pch->alarm.p_upper = tmp[0+Index] & BIT(3);
  504. pch->alarm.w_upper = tmp[0+Index] & BIT(4);
  505. }
  506. offset = POWER_AC3_ALARM_MISSING_PH;
  507. r = read_reg(h, pbrd->addr, offset, tmp, pbrd->chs);
  508. if (r < 0) {
  509. LOGE("read_reg failed, addr:%d reg:0x%04x/%d cnt:%d\n", pbrd->addr, offset, offset, pbrd->chs);
  510. break;
  511. }
  512. v = 0;
  513. for(i = 0; i < 3; i++) {
  514. if(tmp[i * 2]>0) {
  515. v |= 1<<i;
  516. }
  517. }
  518. pbrd->ph_loss = v;
  519. }
  520. break;
  521. case AC_MULTI_S_TYPE:
  522. case AC_MULTI_B_TYPE:
  523. case DC_OUT_TYPE:
  524. case DC_IN_TYPE:
  525. default:
  526. r = -1;
  527. break;
  528. }
  529. if(r==0) {
  530. threshold_proc(h, pbrd);
  531. }
  532. }
  533. lock_off(h->lck);
  534. return r;
  535. }
  536. static int power_copy(power_handle_t *h)
  537. {
  538. int i,r=-1;
  539. power_data_t *pd=&h->pdat;
  540. if(h->chs>0) {
  541. if(!pd->pch || pd->chs!=h->chs) {
  542. if(pd->pch) free(pd->pch);
  543. pd->chs = 0;
  544. pd->pch = malloc(sizeof(power_ch_t)*h->chs);
  545. }
  546. if(pd->pch) {
  547. pd->chs = h->chs;
  548. for(i=0; i<pd->chs; i++) {
  549. pd->pch[i] = *h->pch[i];
  550. }
  551. }
  552. }
  553. pd->ttl = h->ttl;
  554. return 0;
  555. }
  556. static int board_query(power_handle_t *h)
  557. {
  558. int i,r;
  559. for(i=0; i<h->brd_max; i++) {
  560. r = board_read(h, h->pbrd[i]);
  561. }
  562. total_proc(h);
  563. power_copy(h);
  564. return r;
  565. }
  566. static void power_thread(void *arg)
  567. {
  568. int r;
  569. board_data_t *pbrd=NULL;
  570. thread_handle_t *th=(thread_handle_t*)arg;
  571. power_handle_t *h=(power_handle_t*)th->attr->arg;;
  572. while(th->quit==0) {
  573. board_query(h);
  574. sleep(1);
  575. }
  576. }
  577. int power_init(void)
  578. {
  579. power_handle_t *h=&pwrHandle;
  580. mb_para_t para={
  581. .mode = MB_MODE_MASTER,
  582. .type = MB_TYPE_RTU,
  583. .para = {
  584. .rtu = {
  585. .dev = POWER_PORT, //设备名
  586. .baudrate = 115200, //波特率
  587. .parity = 0, //校验位
  588. .pin = -1, //收发控制引脚, <0 表示不使用
  589. .lvl = 0, //发送控制电平
  590. }
  591. }
  592. };
  593. memset(h, 0, sizeof(power_handle_t));
  594. h->lck = lock_init();
  595. h->mb = mb_init(&para);
  596. if(!h->mb) {
  597. return -1;
  598. }
  599. h->cur_addr = 0;
  600. h->brd_max = BRD_NUM;
  601. h->prod = &paras_get()->prod;
  602. power_scan();
  603. power_set_all_sw(1);
  604. thread_start(THREAD_ID_POWER, power_thread, h);
  605. return 0;
  606. }
  607. int power_deinit(void)
  608. {
  609. power_handle_t *h=&pwrHandle;
  610. lock_deinit(h->lck);
  611. mb_deinit(h->mb);
  612. return 0;
  613. }
  614. static int get_ch(power_handle_t *h, uint8_t ch, power_ch_t *pch)
  615. {
  616. if(!pch || !h->pch || !h->chs || !h->pch[ch]) {
  617. return -1;
  618. }
  619. *pch = *h->pch[ch];
  620. return 0;
  621. }
  622. int power_get_ch(uint8_t ch, power_ch_t *pch)
  623. {
  624. int r;
  625. power_handle_t *h=&pwrHandle;
  626. lock_on(h->lck);
  627. r = get_ch(h, ch, pch);
  628. lock_off(h->lck);
  629. return r;
  630. }
  631. int power_get_board(board_data_t *pb)
  632. {
  633. power_handle_t *h=&pwrHandle;
  634. lock_on(h->lck);
  635. if(!pb || !h->pch || !h->cnt || !h->pbrd[pb->addr]) {
  636. lock_off(h->lck);
  637. return -1;
  638. }
  639. *pb = *h->pbrd[pb->addr];
  640. lock_off(h->lck);
  641. return 0;
  642. }
  643. int power_set(int ch, power_ch_t *pch)
  644. {
  645. power_handle_t *h=&pwrHandle;
  646. lock_on(h->lck);
  647. if(!pch || !h->pch || !h->chs || !h->pch[pch->info.ch]) {
  648. lock_off(h->lck);
  649. return -1;
  650. }
  651. *h->pch[pch->info.ch] = *pch;
  652. lock_off(h->lck);
  653. return 0;
  654. }
  655. static int power_map(power_handle_t *h, int chs)
  656. {
  657. int i,j,r,idx=1;
  658. board_data_t *pbrd=NULL;
  659. uint8_t pwr_type=paras_get()->prod.pwr_type;
  660. if(chs>0) {
  661. h->chs = 0;
  662. h->pch = (power_ch_t**)calloc(1, sizeof(power_ch_t*)*chs);
  663. if(h->pch) {
  664. h->chs = chs;
  665. h->pch[0] = &h->ch0;
  666. strcpy(h->pch[0]->info.name, "ALL");
  667. for(i=1; i<=h->brd_max; i++) {
  668. pbrd = h->pbrd[i];
  669. if(pbrd) {
  670. for(j=0; j<pbrd->chs; j++) {
  671. h->pch[idx] = &h->pbrd[i]->pch[j];
  672. sprintf(h->pch[idx]->info.name, "CH%d", idx);
  673. idx++;
  674. }
  675. }
  676. }
  677. }
  678. }
  679. return 0;
  680. }
  681. static int power_clear(power_handle_t *h)
  682. {
  683. int i,j;
  684. memset(&h->ch0, 0, sizeof(h->ch0));
  685. for(i=0; i<=h->brd_max; i++) {
  686. if(h->pbrd[i]) {
  687. for(j=0; j<h->pbrd[i]->chs; j++) {
  688. if(h->pbrd[i]->pch) {
  689. free(h->pbrd[i]->pch);
  690. h->pbrd[i]->pch = NULL;
  691. }
  692. h->pbrd[i]->chs = 0;
  693. }
  694. free(h->pbrd[i]);
  695. h->pbrd[i] = NULL;
  696. }
  697. }
  698. memset(h->key, 0, sizeof(h->key));
  699. h->cnt = 0;
  700. h->cur_addr = 0;
  701. return 0;
  702. }
  703. int power_scan(void)
  704. {
  705. int r,i,j,total_chs=1;
  706. int ch_idx=1,brd_idx=0;
  707. power_ch_t *pch=NULL;
  708. board_key_t *pkey=NULL;
  709. board_data_t *pbrd=NULL;
  710. power_handle_t *h=&pwrHandle;
  711. uint16_t times,nGroups=h->prod->ch_delay;
  712. lock_on(h->lck);
  713. power_clear(h);
  714. pch = &h->ch0;
  715. pch->info.addr = 0;
  716. pch->info.ch = 0;
  717. for(i=1; i<=h->brd_max; i++) {
  718. r = get_key(h, i, &h->key[i]);
  719. if(r==0) {
  720. LOGD("___ power_scan addr %d ok, type: %d, chs: %d\n", i, h->key[i].type, h->key[i].chs);
  721. h->cnt++;
  722. }
  723. else {
  724. LOGE("___ power_scan addr %d failed\n", i);
  725. }
  726. }
  727. for(i=1; i<h->brd_max; i++) {
  728. pkey = &h->key[i];
  729. if(pkey->chs>0) {
  730. pbrd = (board_data_t*)calloc(1, sizeof(board_data_t));
  731. if(!pbrd) {
  732. LOGE("___ power_scan, calloc pbrd %d failed\n", i);
  733. return -1;
  734. }
  735. pbrd->type = pkey->type;
  736. pbrd->chs = pkey->chs;
  737. pbrd->addr = i;
  738. pbrd->ch0 = ch_idx;
  739. pch = (power_ch_t*)calloc(1, sizeof(power_ch_t)*pkey->chs);
  740. if(!pch) {
  741. LOGE("___ power_scan, calloc pch failed\n");
  742. return -1;
  743. }
  744. times = (ch_idx%nGroups)?ch_idx:nGroups;
  745. for(j=0; j<pkey->chs; j++) {
  746. pch[j].info.addr = i;
  747. pch[j].info.sch = j; //序号从0开始
  748. pch[j].info.type = pkey->type;
  749. pch[j].info.start_delay = 1000*times;
  750. pch[j].info.stop_delay = 1000*times;
  751. if(h->prod->pwr_type==PDU_AC_I3O3) {
  752. pch[j].info.ch = ch_idx+j/3; //序号从1开始, 发给控制板需从0开始
  753. pch[j].info.ph_id = j%3;
  754. }
  755. else {
  756. pch[j].info.ch = ch_idx+j; //序号从1开始, 发给控制板需从0开始
  757. pch[j].info.ph_id = 0;
  758. }
  759. }
  760. if(h->prod->pwr_type==PDU_AC_I3O3) {
  761. ch_idx += pkey->chs/3;
  762. }
  763. else {
  764. ch_idx += pkey->chs;
  765. }
  766. brd_idx++;
  767. pbrd->pch = pch;
  768. h->pbrd[i] = pbrd;
  769. total_chs += pkey->chs;
  770. }
  771. }
  772. power_map(h, total_chs);
  773. lock_off(h->lck);
  774. return 0;
  775. }
  776. int power_reset(void)
  777. {
  778. int i,r=-1;
  779. uint16_t offset = 0;
  780. power_handle_t *h=&pwrHandle;
  781. board_data_t *pbrd=NULL;
  782. lock_on(h->lck);
  783. for(i=0; i<=h->brd_max; i++) {
  784. pbrd = h->pbrd[i];
  785. if(pbrd) {
  786. switch(pbrd->type) {
  787. case AC_SINGLE_S_TYPE:
  788. case AC_SINGLE_B_TYPE:
  789. {
  790. uint16_t tmp[8];
  791. offset = POWER_AC_CH_STAT_L;
  792. for(i=1; i<=pbrd->chs; i++) {
  793. tmp[i] = pbrd->pch[i].power[0].status;
  794. }
  795. r = write_reg(h, pbrd->addr, offset, tmp+1, pbrd->chs-1);
  796. }
  797. break;
  798. case DCPDU_TYPE:
  799. {
  800. offset = POWER_DC_ALARM_CTRL_TOTAL;
  801. }
  802. break;
  803. case TREE_AC_TYPE:
  804. {
  805. uint16_t data_temp[20];
  806. offset = POWER_AC3_RESET_CONSUMP;
  807. data_temp[0] = data_temp[1] = data_temp[2] = 1;
  808. r = write_reg(h, pbrd->addr, offset, data_temp, 3);
  809. if (r<0) {
  810. break;
  811. }
  812. //初始化报警阈值
  813. uint32_t value = 0;
  814. memset(data_temp, 0, sizeof(data_temp));
  815. offset = POWER_AC3_THRESHOLD_VOL_MAX;
  816. r = write_reg(h, pbrd->addr, offset, data_temp, 18);
  817. if (r<0) {
  818. break;
  819. }
  820. offset = POWER_AC3_THRESHOLD_VOL_MIN;
  821. r = write_reg(h, pbrd->addr, offset, data_temp, 18);
  822. if (r<0) {
  823. break;
  824. }
  825. offset = POWER_AC3_THRESHOLD_CUR_MAX;
  826. r = write_reg(h, pbrd->addr, offset, data_temp, 18);
  827. if (r<0) {
  828. break;
  829. }
  830. offset = POWER_AC3_THRESHOLD_PWR_MAX;
  831. r = write_reg(h, pbrd->addr, offset, data_temp, 18);
  832. if (r<0) {
  833. break;
  834. }
  835. offset = POWER_AC3_THRESHOLD_PWRCON_MAX;
  836. r = write_reg(h, pbrd->addr, offset, data_temp, 18);
  837. if (r<0) {
  838. break;
  839. }
  840. for (i=1; i<=pbrd->chs; i++) {
  841. memset(data_temp, 0, sizeof(data_temp));
  842. offset = POWER_AC3_OUT_ENABLE + i;
  843. data_temp[0] = pbrd->pch[i].power[0].status;
  844. r = write_reg(h, pbrd->addr, offset, data_temp, 2);
  845. }
  846. }
  847. break;
  848. }
  849. }
  850. }
  851. lock_off(h->lck);
  852. return r;
  853. }
  854. int power_set_ch_sw(uint8_t ch, uint8_t on)
  855. {
  856. int r;
  857. power_ch_t pc,*pch;
  858. power_handle_t *h=&pwrHandle;
  859. uint16_t offset,tmp[2]={0},st=on;
  860. lock_on(h->lck);
  861. r = get_ch(h, ch, &pc);
  862. if(r) {
  863. lock_off(h->lck);
  864. return -1;
  865. }
  866. pch = &pc;
  867. if (pch->thr.v_upper.en == 1)
  868. st |= ENABLE_AC3_V_UP;
  869. if (pch->thr.v_lower.en == 1)
  870. st |= ENABLE_AC3_V_DOWN;
  871. if (pch->thr.c_upper.en == 1)
  872. st |= ENABLE_AC3_C_UP;
  873. if (pch->thr.p_upper.en == 1)
  874. st |= ENABLE_AC3_P_UP;
  875. if (pch->thr.w_upper.en == 1)
  876. st |= ENABLE_AC3_W_UP;
  877. switch(pch->info.type) {
  878. case AC_SINGLE_S_TYPE:
  879. case AC_SINGLE_B_TYPE:
  880. {
  881. offset = POWER_AC_CH_STAT_L + pch->info.ch-1;
  882. tmp[0] = st; tmp[1] = 0;
  883. r = write_reg(h, pc.info.addr, offset, tmp, 2);
  884. }
  885. break;
  886. case DCPDU_TYPE:
  887. {
  888. uint16_t mask;
  889. offset = POWER_DC_STAT_INFO+pch->info.ch-1;
  890. mask = ~(1 << (pch->info.ch-1));
  891. tmp[0] &= mask;
  892. tmp[0] |= (st << (pch->info.ch-1));
  893. r = write_reg(h, pc.info.addr, offset, tmp, 2);
  894. }
  895. break;
  896. case TREE_AC_TYPE:
  897. {
  898. uint16_t reg;
  899. uint8_t pwr_type=paras_get()->prod.pwr_type;
  900. if(pwr_type==PDU_AC_I3O3 || pwr_type==PDU_AC_I3O1) {
  901. reg = POWER_AC3_OUT_ENABLE;
  902. }
  903. else {
  904. reg = POWER_AC3_CH_OUT_ENABLE;
  905. }
  906. tmp[0] = st;
  907. offset = reg + +pch->info.ch-1;
  908. r = write_reg(h, pc.info.addr, offset, tmp, 2);
  909. }
  910. break;
  911. }
  912. lock_off(h->lck);
  913. return r;
  914. }
  915. static int set_board_sw(board_data_t *pbrd, uint8_t on)
  916. {
  917. int i,r;
  918. power_ch_t pc;
  919. power_handle_t *h=&pwrHandle;
  920. if(!pbrd) {
  921. return -1;
  922. }
  923. for(i=1; i<=pbrd->chs; i++) {
  924. r = get_ch(h, i, &pc);
  925. if(r==0) {
  926. power_set_ch_sw(pc.info.ch, on);
  927. }
  928. }
  929. return 0;
  930. }
  931. int power_set_all_sw(uint8_t on)
  932. {
  933. int i,r;
  934. power_handle_t *h=&pwrHandle;
  935. for(i=1; i<=h->chs; i++) {
  936. power_set_ch_sw(i, on);
  937. }
  938. return 0;
  939. }
  940. int power_set_alarm(power_ch_t *pch)
  941. {
  942. int r=0;
  943. uint16_t offset = 0;
  944. uint16_t nStatus = 0;
  945. power_handle_t *h=&pwrHandle;
  946. lock_on(h->lck);
  947. switch(pch->info.type) {
  948. case AC_SINGLE_S_TYPE:
  949. case AC_SINGLE_B_TYPE:
  950. {
  951. if (pch->info.ch==0) {
  952. offset = POWER_AC_ALARM_CTRL_TOTAL;
  953. }
  954. else {
  955. offset = POWER_AC_ALARM_CTRL + pch->info.ch-1;
  956. }
  957. }
  958. break;
  959. case DCPDU_TYPE:
  960. {
  961. if (pch->info.ch==0) {
  962. offset = POWER_DC_ALARM_CTRL_TOTAL;
  963. }
  964. else {
  965. offset = POWER_DC_ALARM_CTRL + pch->info.ch-1;
  966. }
  967. }
  968. break;
  969. case TREE_AC_TYPE:
  970. {
  971. if (pch->info.ch==0) {
  972. offset = POWER_AC3_ALARM_CTRL_TOTAL;
  973. }
  974. else {
  975. offset = POWER_AC3_ALARM_CTRL + pch->info.ch-1;
  976. }
  977. }
  978. break;
  979. default:
  980. r = -1;
  981. }
  982. if(r==0) {
  983. if(pch->thr.v_upper.act==1) nStatus |= BIT(1);
  984. if(pch->thr.v_lower.act==1) nStatus |= BIT(2);
  985. if(pch->thr.c_upper.act==1) nStatus |= BIT(0);
  986. if(pch->thr.p_upper.act==1) nStatus |= BIT(3);
  987. if(pch->thr.w_upper.act==1) nStatus |= BIT(4);
  988. r = write_reg(h, pch->info.addr, offset, &nStatus, 1);
  989. }
  990. lock_off(h->lck);
  991. return r;
  992. }
  993. int power_set_threshold(power_ch_t *pch)
  994. {
  995. int r=0;
  996. uint16_t offset;
  997. power_handle_t *h=&pwrHandle;
  998. lock_on(h->lck);
  999. switch(pch->info.type) {
  1000. case AC_SINGLE_S_TYPE:
  1001. case AC_SINGLE_B_TYPE:
  1002. {
  1003. uint16_t offset = 0;
  1004. uint32_t data_temp = 0 ;
  1005. uint16_t data_buf[16] = {0};
  1006. //电压上限
  1007. data_temp = (pch->thr.v_upper.val*1000);
  1008. data_buf[0] = data_temp;
  1009. data_buf[1] = data_temp>>16;
  1010. //电压下限
  1011. data_temp = (pch->thr.v_upper.val*1000);
  1012. data_buf[2] = data_temp;
  1013. data_buf[3] = data_temp>>16;
  1014. //电流上限
  1015. data_temp = (pch->thr.v_upper.val*1000);
  1016. data_buf[4] = data_temp;
  1017. data_buf[5] = data_temp>>16;
  1018. //电流下限
  1019. data_temp = (0);
  1020. data_buf[6] = data_temp;
  1021. data_buf[7] = data_temp>>16;
  1022. //功率上限
  1023. data_temp = (pch->thr.v_upper.val*1000);
  1024. data_buf[8] = data_temp;
  1025. data_buf[9] = data_temp>>16;
  1026. //功率下限
  1027. data_temp = 0;
  1028. data_buf[10] = data_temp;
  1029. data_buf[11] = data_temp>>16;
  1030. //电能上限
  1031. data_temp = (pch->thr.v_upper.val*1000);
  1032. data_buf[12] = data_temp;
  1033. data_buf[13] = data_temp>>16;
  1034. //电能下限
  1035. data_temp = 0;
  1036. data_buf[14] = data_temp;
  1037. data_buf[15] = data_temp>>16;
  1038. if(pch->info.ch==0) {
  1039. offset = POWER_AC_TOTAL_THRESHOLD;
  1040. }
  1041. else {
  1042. offset = POWER_AC_THRESHOLD_L+(pch->info.ch-1)*16;
  1043. }
  1044. r = write_reg(h, pch->info.addr, offset, data_buf, 16);
  1045. //power_set_alarm();
  1046. }
  1047. break;
  1048. case DCPDU_TYPE:
  1049. {
  1050. uint16_t data_temp[4];
  1051. uint32_t value;
  1052. offset = (pch->info.ch<0)?POWER_DC_THRESHOLD_TOTAL_VOL_MAX:POWER_DC_THRESHOLD_VOL_MAX;
  1053. value = pch->thr.v_upper.val * 1000;
  1054. data_temp[0] = value & 0XFFFF;
  1055. data_temp[1] = (value >> 16) & 0xFFFF;
  1056. r = write_reg(h, pch->info.addr, offset, data_temp, 2);
  1057. offset = (pch->info.ch<0)?POWER_DC_THRESHOLD_TOTAL_VOL_MIN:POWER_DC_THRESHOLD_VOL_MIN;
  1058. value = pch->thr.v_lower.val * 1000;
  1059. data_temp[0] = value & 0XFFFF;
  1060. data_temp[1] = (value >> 16) & 0xFFFF;
  1061. r = write_reg(h, pch->info.addr, offset, data_temp, 2);
  1062. offset = (pch->info.ch<0)?POWER_DC_THRESHOLD_TOTAL_CUR_MAX:POWER_DC_THRESHOLD_CUR_MAX;
  1063. value = pch->thr.c_upper.val * 1000;
  1064. data_temp[0] = value & 0XFFFF;
  1065. data_temp[1] = (value >> 16) & 0xFFFF;
  1066. r = write_reg(h, pch->info.addr, offset, data_temp, 2);
  1067. offset = (pch->info.ch<0)?POWER_DC_THRESHOLD_TOTAL_PWR_MAX:POWER_DC_THRESHOLD_POWER_MAX;
  1068. value = pch->thr.p_upper.val * 1000;
  1069. data_temp[0] = value & 0XFFFF;
  1070. data_temp[1] = (value >> 16) & 0xFFFF;
  1071. r = write_reg(h, pch->info.addr, offset, data_temp, 2);
  1072. offset = (pch->info.ch<0)?POWER_DC_THRESHOLD_TOTAL_PWRCON_MAX:POWER_DC_THRESHOLD_POWERCON_MAX;
  1073. value = pch->thr.w_upper.val * 1000;
  1074. data_temp[0] = value & 0XFFFF;
  1075. data_temp[1] = (value >> 16) & 0xFFFF;
  1076. r = write_reg(h, pch->info.addr, offset, data_temp, 2);
  1077. //power_set_alarm();
  1078. }
  1079. break;
  1080. case TREE_AC_TYPE:
  1081. {
  1082. uint16_t data_temp[4];
  1083. uint32_t value;
  1084. if(pch->info.ch<0) {
  1085. offset = POWER_AC3_THRESHOLD_IN;
  1086. value = pch->thr.v_upper.val * 1000;
  1087. data_temp[0] = value & 0XFFFF;
  1088. data_temp[1] = (value >> 16) & 0xFFFF;
  1089. r = write_reg(h, pch->info.addr, offset, data_temp, 2);
  1090. value = pch->thr.v_upper.val * 1000;
  1091. data_temp[0] = value & 0XFFFF;
  1092. data_temp[1] = (value >> 16) & 0xFFFF;
  1093. r = write_reg(h, pch->info.addr, offset+1, data_temp, 2);
  1094. value = pch->thr.c_upper.val * 1000;
  1095. data_temp[0] = value & 0XFFFF;
  1096. data_temp[1] = (value >> 16) & 0xFFFF;
  1097. r = write_reg(h, pch->info.addr, offset+2, data_temp, 2);
  1098. value = pch->thr.p_upper.val * 1000;
  1099. data_temp[0] = value & 0XFFFF;
  1100. data_temp[1] = (value >> 16) & 0xFFFF;
  1101. r = write_reg(h, pch->info.addr, offset+3, data_temp, 2);
  1102. value = pch->thr.w_upper.val * 1000;
  1103. data_temp[0] = value & 0XFFFF;
  1104. data_temp[1] = (value >> 16) & 0xFFFF;
  1105. r = write_reg(h, pch->info.addr, offset+4, data_temp, 2);
  1106. }
  1107. else {
  1108. offset = POWER_AC3_THRESHOLD_VOL_MAX;
  1109. value = pch->thr.v_upper.val * 1000;
  1110. data_temp[0] = value & 0XFFFF;
  1111. data_temp[1] = (value >> 16) & 0xFFFF;
  1112. r = write_reg(h, pch->info.addr, offset, data_temp, 2);
  1113. offset = POWER_AC3_THRESHOLD_VOL_MIN;
  1114. value = pch->thr.v_lower.val * 1000;
  1115. data_temp[0] = value & 0XFFFF;
  1116. data_temp[1] = (value >> 16) & 0xFFFF;
  1117. r = write_reg(h, pch->info.addr, offset, data_temp, 2);
  1118. offset = POWER_AC3_THRESHOLD_CUR_MAX;
  1119. value = pch->thr.c_upper.val * 1000;
  1120. data_temp[0] = value & 0XFFFF;
  1121. data_temp[1] = (value >> 16) & 0xFFFF;
  1122. r = write_reg(h, pch->info.addr, offset, data_temp, 2);
  1123. offset = POWER_AC3_THRESHOLD_PWR_MAX;
  1124. value = pch->thr.p_upper.val * 1000;
  1125. data_temp[0] = value & 0XFFFF;
  1126. data_temp[1] = (value >> 16) & 0xFFFF;
  1127. r = write_reg(h, pch->info.addr, offset, data_temp, 2);
  1128. offset = POWER_AC3_THRESHOLD_VOL_MAX;
  1129. value = pch->thr.w_upper.val * 1000;
  1130. data_temp[0] = value & 0XFFFF;
  1131. data_temp[1] = (value >> 16) & 0xFFFF;
  1132. r = write_reg(h, pch->info.addr, offset, data_temp, 2);
  1133. }
  1134. }
  1135. break;
  1136. default:
  1137. r = -1;
  1138. break;
  1139. }
  1140. lock_off(h->lck);
  1141. return r;
  1142. }
  1143. int power_set_start_delay(power_ch_t *pch)
  1144. {
  1145. int r=-1;
  1146. uint16_t tmp[2],reg,offset;
  1147. power_handle_t *h=&pwrHandle;
  1148. lock_on(h->lck);
  1149. switch(pch->info.type) {
  1150. case AC_SINGLE_S_TYPE:
  1151. case AC_SINGLE_B_TYPE:
  1152. {
  1153. tmp[0] = pch->info.start_delay;
  1154. offset = POWER_AC_START_DELAY_TIME_L+pch->info.ch-1;
  1155. r = write_reg(h, pch->info.addr, offset, tmp, 1);
  1156. }
  1157. break;
  1158. case DCPDU_TYPE:
  1159. {
  1160. uint32_t time=pch->info.start_delay/1000;
  1161. tmp[0] = time & 0xffff;
  1162. tmp[1] = (time >> 16) & 0xffff;
  1163. offset = POWER_DC_SET_START_DELAY+pch->info.ch-1;
  1164. r = write_reg(h, pch->info.addr, offset, tmp, 2);
  1165. }
  1166. break;
  1167. case TREE_AC_TYPE:
  1168. {
  1169. uint32_t time=pch->info.start_delay/1000;
  1170. tmp[0] = time & 0xffff;
  1171. tmp[1] = (time >> 16) & 0xffff;
  1172. if(h->prod->pwr_type==PDU_AC_I3O3) {
  1173. offset = POWER_AC3_START_DELAY_TIME+pch->info.sch*3;
  1174. r = write_reg(h, pch->info.addr, offset+0, tmp, 2);
  1175. if(r) break;
  1176. r = write_reg(h, pch->info.addr, offset+1, tmp, 2);
  1177. if(r) break;
  1178. r = write_reg(h, pch->info.addr, offset+2, tmp, 2);
  1179. if(r) break;
  1180. }
  1181. else {
  1182. offset = POWER_AC3_START_DELAY_TIME+pch->info.sch;
  1183. r = write_reg(h, pch->info.addr, offset, tmp, 2);
  1184. }
  1185. }
  1186. break;
  1187. case AC_MULTI_S_TYPE:
  1188. case AC_MULTI_B_TYPE:
  1189. case DC_OUT_TYPE:
  1190. case DC_IN_TYPE:
  1191. default:
  1192. r = -1;
  1193. }
  1194. lock_off(h->lck);
  1195. return r;
  1196. }
  1197. int power_set_stop_delay(power_ch_t *pch)
  1198. {
  1199. int r=-1;
  1200. uint16_t tmp[2],reg,offset;
  1201. power_handle_t *h=&pwrHandle;
  1202. lock_off(h->lck);
  1203. switch(pch->info.type) {
  1204. case AC_SINGLE_S_TYPE:
  1205. case AC_SINGLE_B_TYPE:
  1206. {
  1207. tmp[0] = pch->info.start_delay;
  1208. offset = POWER_AC_STOP_DELAY_TIME_L+pch->info.ch-1;
  1209. r = write_reg(h, pch->info.addr, offset, tmp, 1);
  1210. }
  1211. break;
  1212. case DCPDU_TYPE:
  1213. {
  1214. uint32_t time=pch->info.stop_delay/1000;
  1215. tmp[0] = time & 0xffff;
  1216. tmp[1] = (time >> 16) & 0xffff;
  1217. offset = POWER_DC_SET_STOP_DELAY+pch->info.ch-1;
  1218. //r = write_reg(h, pch->info.addr, offset, tmp, 2);
  1219. }
  1220. break;
  1221. case TREE_AC_TYPE:
  1222. {
  1223. uint32_t time=pch->info.stop_delay/1000;
  1224. if(h->prod->pwr_type==PDU_AC_I3O3) {
  1225. offset = POWER_AC3_STOP_DELAY_TIME+pch->info.sch*3;
  1226. r = write_reg(h, pch->info.addr, offset+0, tmp, 2);
  1227. if(r) break;
  1228. r = write_reg(h, pch->info.addr, offset+1, tmp, 2);
  1229. if(r) break;
  1230. r = write_reg(h, pch->info.addr, offset+2, tmp, 2);
  1231. if(r) break;
  1232. }
  1233. else {
  1234. offset = POWER_AC3_START_DELAY_TIME+pch->info.sch;
  1235. r = write_reg(h, pch->info.addr, offset, tmp, 2);
  1236. }
  1237. }
  1238. break;
  1239. case AC_MULTI_S_TYPE:
  1240. case AC_MULTI_B_TYPE:
  1241. case DC_OUT_TYPE:
  1242. case DC_IN_TYPE:
  1243. default:
  1244. r = -1;
  1245. break;
  1246. }
  1247. lock_on(h->lck);
  1248. return r;
  1249. }
  1250. power_data_t power_data_get(void)
  1251. {
  1252. power_handle_t *h=&pwrHandle;
  1253. return h->pdat;
  1254. }