breaker.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. #include <stdlib.h>
  2. #include "sys/time.h"
  3. #include "mb.h"
  4. #include "lock.h"
  5. #include "list.h"
  6. #include "power.h"
  7. #include "cascade.h"
  8. #include "breaker.h"
  9. #define RETRY_TIMES 3
  10. #define TIMEOUT 200
  11. #define BREAKER_INFO_REG 2200
  12. typedef struct {
  13. int8_t data;
  14. uint32_t time;
  15. }breaker_ori_t;
  16. typedef struct {
  17. lock_t lck;
  18. uint8_t cur_idx;
  19. breaker_ori_t ori[BREAKER_BOARD_MAX];
  20. }breaker_handle_t;
  21. static breaker_handle_t brHandle={0};
  22. static int read_reg(uint8_t addr, uint16_t reg, uint16_t *data, int cnt)
  23. {
  24. int i,r=0;
  25. cascade_lock(1);
  26. for(i=0; i<RETRY_TIMES; i++) {
  27. r = mb_read(MB_ID_POWER, addr, reg, data, cnt, TIMEOUT);
  28. if(r==cnt) {
  29. break;
  30. }
  31. }
  32. cascade_lock(0);
  33. return (r==cnt)?0:-1;
  34. }
  35. int breaker_init(void)
  36. {
  37. int i;
  38. breaker_handle_t *h=&brHandle;
  39. h->lck = lock_init();
  40. for(i=0; i<BREAKER_BOARD_MAX; i++) {
  41. h->ori[i].data = -1;
  42. }
  43. return 0;
  44. }
  45. int breaker_deinit(void)
  46. {
  47. breaker_handle_t *h=&brHandle;
  48. lock_deinit(h->lck);
  49. return 0;
  50. }
  51. static int read_board(breaker_handle_t *h, uint8_t addr, int8_t *sw)
  52. {
  53. int i,r;
  54. uint16_t tmp[BREAKER_CH_MAX];
  55. r = read_reg(addr, BREAKER_INFO_REG+1, tmp, BREAKER_CH_MAX);
  56. if(r==0) {
  57. for(i=0; i<BREAKER_CH_MAX; i++) {
  58. *sw |= BIT(i);
  59. }
  60. }
  61. else {
  62. *sw = -1;
  63. }
  64. return r;
  65. }
  66. static breaker_all_t brk_get(breaker_handle_t *h)
  67. {
  68. int i,j,idx=0;
  69. breaker_all_t all={0};
  70. for(i=0; i<BREAKER_BOARD_MAX; i++) {
  71. if(h->ori[i].data>=0) {
  72. all.cnt += BREAKER_CH_MAX;
  73. }
  74. }
  75. if(all.cnt>0) {
  76. all.data = (breaker_data_t*)malloc(sizeof(breaker_data_t*)*all.cnt);
  77. if(all.data) {
  78. for(i=0; i<BREAKER_BOARD_MAX; i++) {
  79. if(h->ori[i].data>=0) {
  80. for(j=0; j<BREAKER_CH_MAX; j++) {
  81. all.data[idx].info.addr = BREAKER_BOARD_ADDR_START+i;
  82. all.data[idx].samp.sw = (h->ori[i].data&BIT(j))?1:0;
  83. idx++;
  84. }
  85. }
  86. }
  87. }
  88. else {
  89. all.cnt = 0;
  90. }
  91. }
  92. return all;
  93. }
  94. int breaker_query(void)
  95. {
  96. int i,r;
  97. uint8_t addr;
  98. breaker_handle_t *h=&brHandle;
  99. lock_on(h->lck);
  100. if(h->cur_idx>=BREAKER_BOARD_MAX) {
  101. h->cur_idx = 0;
  102. }
  103. addr = BREAKER_BOARD_ADDR_START+h->cur_idx;
  104. r = read_board(h, addr, &h->ori[h->cur_idx].data);
  105. if(r) {
  106. h->ori[h->cur_idx].data = -1;
  107. }
  108. h->ori[h->cur_idx].time = mktime(localtime(NULL));
  109. lock_off(h->lck);
  110. return r;
  111. }
  112. int breaker_set(breaker_data_t *data)
  113. {
  114. breaker_handle_t *h=&brHandle;
  115. if(!data) {
  116. return -1;
  117. }
  118. lock_on(h->lck);
  119. lock_off(h->lck);
  120. return 0;
  121. }
  122. int breaker_data_get(breaker_all_t *all)
  123. {
  124. int i,cnt;
  125. char *p=NULL;
  126. breaker_all_t brk={0};
  127. breaker_handle_t *h=&brHandle;
  128. if(!all) {
  129. return -1;
  130. }
  131. lock_on(h->lck);
  132. power_breaker_get(all);
  133. brk = brk_get(h);
  134. if(brk.cnt) {
  135. cnt = all->cnt+brk.cnt;
  136. p = (char*)realloc(all->data, sizeof(breaker_data_t)*cnt);
  137. if(p) {
  138. memcpy(p+sizeof(breaker_data_t)*cnt, brk.data, sizeof(breaker_data_t)*brk.cnt);
  139. all->data = (breaker_data_t*)p;
  140. all->cnt = cnt;
  141. }
  142. }
  143. breaker_data_free(&brk);
  144. for(i=0; i<all->cnt; i++) {
  145. sprintf(all->data[i].info.name, "SW%d", i);
  146. all->data[i].samp.id = i;
  147. all->data[i].samp.nid = 0;
  148. }
  149. lock_off(h->lck);
  150. return 0;
  151. }
  152. int breaker_data_free(breaker_all_t *all)
  153. {
  154. if(!all) {
  155. return -1;
  156. }
  157. if(all->data) {
  158. free(all->data);
  159. all->data = NULL;
  160. }
  161. all->cnt = 0;
  162. return 0;
  163. }