oiltank.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. #include "includes.h"
  2. #include "device.h"
  3. #include "tax_ctrl.h"
  4. #include "net_proc.h"
  5. #include "oiltank.h"
  6. typedef union {
  7. u8 c[5];
  8. u32 i;
  9. } uData_t;
  10. typedef union {
  11. u32 i;
  12. float f;
  13. } uData1_t;
  14. system_oiltank_info_t system_oiltank;
  15. //CRC校验(本质和校验)
  16. static u32 _check_sum(u8 buf[], u32 len)
  17. {
  18. u32 i, check_sum = 0;
  19. uData_t data;
  20. for(i=0; i< len; i++) {
  21. check_sum += buf[i];
  22. }
  23. #if 0
  24. check_sum = ~check_sum;
  25. check_sum &= 0xffff;
  26. check_sum += 1;
  27. #else
  28. check_sum &= 0xffff;
  29. check_sum = 0xffff-check_sum+1;
  30. #endif
  31. snprintf(data.c, sizeof(data.c), "%04X", check_sum);
  32. return data.i;
  33. }
  34. static u32 _str_to_hex(uint8_t *data)
  35. {
  36. u8 i, ch;
  37. u32 hex = 0;
  38. //data_dump("====", data, 8);
  39. for(i = 0;i < 8;i++) {
  40. if(isdigit(data[i])) {
  41. ch = data[i] - '0' + 0x0;
  42. } else if(isalpha(data[i])){
  43. ch = data[i] - 'A' + 0xA;
  44. }
  45. hex = (hex<<4)|ch;
  46. }
  47. //printf("%08x, %0.2f\r\n", hex, (float)(hex));
  48. return (hex);
  49. }
  50. int oiltank_data_update(I201_FUELTANK_DATA *p_data)
  51. {
  52. uData1_t data;
  53. oiltank_info_t *p_tank = NULL;
  54. u8 id = 0;
  55. id = p_data->TT[1] - '0';
  56. if(id > OILTANK_VALID_COUNT) {
  57. return 0;
  58. }
  59. //data_dump("******", (uint8_t * )p_data, YB_SS160_RCV_DATASIZE);
  60. p_tank = &system_oiltank.oiltank[id];
  61. printf("罐号: %c%c\r\n", p_data->TT[0], p_data->TT[1]);
  62. printf("油品: %c\r\n", p_data->P);
  63. printf("油罐状态: %c%c%c%c\r\n", p_data->SSSS[0], p_data->SSSS[1], p_data->SSSS[2], p_data->SSSS[3]);
  64. printf("%c%c 组数据\r\n", p_data->NN[0], p_data->NN[1]);
  65. p_tank->id = id;
  66. BIT_SET(system_oiltank.valid, p_tank->id);
  67. p_tank->quality = p_data->P;
  68. /* 首先来看单精度浮点型float。
  69. float占用4字节空间,也就是32位。
  70. 从左向右数,第1位是符号位(0代表正数,1代表负数),接着是8位指数位,剩下的23位是数据位。如下所示
  71. S EEEEEEEE DDDDDDDDDDDDDDDDDDDDDDD
  72. */
  73. //1、容积;2、TC 容积;3、罐空;4 高度;5、水位;6、温度;7、水容积
  74. p_tank->volume = _str_to_hex(p_data->TankVolume);
  75. printf("Tank Volume : 0x%08x\r\n", p_tank->volume);
  76. //printf("Tank Volume :%0.2f\r\n", data.f);
  77. p_tank->oil_volume = _str_to_hex(p_data->NetVolume);
  78. //printf("Net Volume :%0.2f\r\n", data.f);
  79. data.i = _str_to_hex(p_data->CrossVolume);
  80. //printf("Cross Volume :%0.2f\r\n", data.f);
  81. p_tank->height = _str_to_hex(p_data->Height);
  82. //printf("Height :%0.2f\r\n", data.f);
  83. data.i = _str_to_hex(p_data->Water);
  84. //printf("Water :%0.2f\r\n", data.f);
  85. p_tank->temperature = _str_to_hex(p_data->Temp);
  86. //printf("Temp :%0.2f\r\n", data.f);
  87. p_tank->water_volume = _str_to_hex(p_data->WaterVolume);
  88. //printf("Water Volume :%0.2f\r\n", data.f);
  89. p_tank->valid_num++;
  90. return 0;
  91. }
  92. int oiltank_YB_SS160_cmd_comm(uint8_t uart)
  93. {
  94. int ret = -1;
  95. uint8_t rcv_buf[1024], send_buf[128];
  96. uint32_t i, rcv_size = 0, send_size = YB_SS160_SEND_SIZE, crc;
  97. RS232_YB_SS160_SEND *p_tank_tx = (RS232_YB_SS160_SEND *)send_buf;
  98. RS232_YB_SS160_RECEIVE_HEAD *p_tank_rx_head = (RS232_YB_SS160_RECEIVE_HEAD *)rcv_buf;
  99. RS232_YB_SS160_RECEIVE_TAIL *p_tank_rx_tail = NULL;
  100. I201_FUELTANK_DATA *p_data = NULL;
  101. int FuelTank_Num = 0;
  102. oiltank_info_t *p_tank = NULL;
  103. /* 查询所有油管数据 */
  104. //<SOH>i201TT,
  105. /* <SOH>i201TT
  106. YYMMDDHHmm 日期和时间(年/月/日/时/分)
  107. TTpssssNNFFFFFFFF...
  108. TTpssssNNFFFFFFFF...
  109. &&CCCC<ETX>
  110. */
  111. p_tank_tx->SOH = 0x01;
  112. strcpy((char *)p_tank_tx->FCN_CODE, "i20100");
  113. p_tank_tx->EXT = 0x03;
  114. data_dump("YB_SS160 oiltank send", send_buf, send_size);
  115. uart_msg_send(uart, (char *)p_tank_tx, send_size);
  116. rcv_size = uart_blocking_read((char *)rcv_buf, uart, 5000);
  117. if(rcv_size) {
  118. data_dump("YB_SS160 oiltank recv", rcv_buf, rcv_size);
  119. if(memcmp((char *)p_tank_rx_head->FCN_CODE, "i20100", sizeof(p_tank_rx_head->FCN_CODE)) == 0) {
  120. /* check sum */
  121. p_tank_rx_tail = (RS232_YB_SS160_RECEIVE_TAIL *)(rcv_buf + rcv_size - YB_SS160_RCV_TAILSIZE);
  122. crc = _check_sum(rcv_buf, rcv_size - YB_SS160_RCV_TAILSIZE + 2);
  123. printf("headsize : %d, datasize : %d, tailsize : %d, rcv_size : %d, %x, %x, %x\r\n",
  124. YB_SS160_RCV_HEADSIZE,
  125. YB_SS160_RCV_DATASIZE,
  126. YB_SS160_RCV_TAILSIZE, rcv_size,
  127. p_tank_rx_tail->FCN_FLAG, p_tank_rx_tail->CheckCode , crc);
  128. if((p_tank_rx_tail->FCN_FLAG == YB_SS160_FCN_FLAG)&&
  129. (p_tank_rx_tail->CheckCode == crc)) {
  130. rcv_size -= (YB_SS160_RCV_HEADSIZE + YB_SS160_RCV_TAILSIZE);
  131. FuelTank_Num = rcv_size/YB_SS160_RCV_DATASIZE;
  132. for(i = 0;i < FuelTank_Num;i++) {
  133. p_data = (I201_FUELTANK_DATA *)(rcv_buf + YB_SS160_RCV_HEADSIZE + i*YB_SS160_RCV_DATASIZE);
  134. oiltank_data_update(p_data);
  135. }
  136. }
  137. }
  138. }
  139. for(i = 0;i < OILTANK_VALID_COUNT;i++) {
  140. if(BIT_IS_SET(system_oiltank.valid, 1<<system_oiltank.current)) {
  141. p_tank = &system_oiltank.oiltank[i];
  142. if(p_tank->valid_num == 0) {
  143. BIT_CLC(system_oiltank.valid, i);
  144. memset(p_tank, 0, sizeof(oiltank_info_t));
  145. } else {
  146. p_tank->valid_num = 0;
  147. }
  148. }
  149. }
  150. return ret;
  151. }
  152. void oiltank_polling(void)
  153. {
  154. uint8_t uart = OILTANK_UART;
  155. YTSF_GPIO_RS485_RESET();
  156. YTSF_GPIO_YTSF_RESET();
  157. YTSF_GPIO_AB_SET();
  158. oiltank_YB_SS160_cmd_comm(uart);
  159. }
  160. void oiltank_msg_timer(void *p_tmr, void *p_arg)
  161. {
  162. inner_msg_format_t *p_msg = NULL;
  163. uint32_t *p_collect_time = NULL, i;
  164. gb_oiltank_header_t *p_oiltank_header = NULL;
  165. oiltank_info_t *p_oiltank_info = NULL;
  166. if(system_oiltank.valid == 0) {/* 没有有效数据 */
  167. return ;
  168. }
  169. p_msg = (inner_msg_format_t *)net_queue_mem_calloc();
  170. if(p_msg == NULL) {
  171. return ;
  172. }
  173. //HEADER
  174. p_oiltank_header = (gb_oiltank_header_t *)p_msg->info;
  175. device_type_and_id_get(&p_oiltank_header->device_type, &p_oiltank_header->device_id);
  176. p_oiltank_header->device_status = 0;
  177. p_oiltank_header->oiltank_count = 1;
  178. //OILTANK_INFO
  179. for(i = 0;i < OILTANK_VALID_COUNT;i++) {
  180. system_oiltank.current += i + 1;
  181. system_oiltank.current = system_oiltank.current%OILTANK_VALID_COUNT;
  182. if(BIT_IS_SET(system_oiltank.valid, 1<<system_oiltank.current)) {
  183. break;
  184. }
  185. }
  186. if(i == OILTANK_VALID_COUNT) {
  187. return ;
  188. }
  189. p_oiltank_info = (oiltank_info_t *)(p_msg->info + GB_OILTANK_HEADER_LEN);
  190. #if 0
  191. p_oiltank_info->id = 1;
  192. p_oiltank_info->quality = QUALITY_95;
  193. p_oiltank_info->volume = 100;
  194. p_oiltank_info->oil_volume = 200;
  195. p_oiltank_info->water_volume = 300;
  196. p_oiltank_info->temperature = 50;
  197. p_oiltank_info->height = 400;
  198. #else
  199. memcpy(p_oiltank_info, &system_oiltank.oiltank[system_oiltank.current], GB_OILTANK_INFO_LEN);
  200. #endif
  201. //timestamp
  202. p_collect_time = (uint32_t *)(p_msg->info + GB_OILTANK_HEADER_LEN + GB_OILTANK_INFO_LEN);
  203. *p_collect_time = RTC_GetCounter();
  204. net_msg_frame_fill(p_msg, net_msg_type_oiltank, GB_OILTANK_HEADER_LEN + GB_OILTANK_INFO_LEN + 4);
  205. net_queue_insert((char *)p_msg, sizeof(inner_msg_format_t));
  206. data_dump(MQTT_UPLINK_TANK_TOPIC, (uint8_t *)p_msg, sizeof(inner_msg_format_t));
  207. }
  208. OS_TMR oiltank_timer;
  209. int oiltank_init(void)
  210. {
  211. OS_ERR err;
  212. //GUN CHECK,PC0 - PC 3
  213. GPIO_COMM_Init(RCC_APB2Periph_GPIOC, GPIOC,
  214. GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 , GPIO_Mode_IN_FLOATING, GPIO_Speed_2MHz);
  215. //SW_PORT_RS485、SW_PORT_AB、SW_PORT_CD、SW_PORT_YTSF
  216. GPIO_COMM_Init(RCC_APB2Periph_GPIOD, GPIOD, GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6, GPIO_Mode_Out_PP, GPIO_Speed_2MHz);
  217. //YTSF_REV2
  218. GPIO_COMM_Init(RCC_APB2Periph_GPIOD, GPIOD, GPIO_Pin_7, GPIO_Mode_IPU, GPIO_Speed_2MHz);
  219. //YTSF_RST_N
  220. GPIO_COMM_Init(RCC_APB2Periph_GPIOB, GPIOB, GPIO_Pin_5, GPIO_Mode_Out_PP, GPIO_Speed_2MHz);
  221. YTSF_GPIO_EN();
  222. //YTSF_POSITION_N
  223. GPIO_COMM_Init(RCC_APB2Periph_GPIOB, GPIOB, GPIO_Pin_6, GPIO_Mode_IPU, GPIO_Speed_2MHz);
  224. //YTSF_EN_N
  225. GPIO_COMM_Init(RCC_APB2Periph_GPIOB, GPIOB, GPIO_Pin_7, GPIO_Mode_Out_PP, GPIO_Speed_2MHz);
  226. YTSF_GPIO_DN();
  227. OSTmrCreate(&oiltank_timer, "oiltank_tmr",
  228. OILTANK_MSG_PERIOD, OILTANK_MSG_PERIOD, OS_OPT_TMR_PERIODIC, oiltank_msg_timer, NULL, &err);
  229. OSTmrStart(&oiltank_timer, &err);
  230. YTSF_GPIO_DN();
  231. memset(&system_oiltank, 0 ,sizeof(system_oiltank_info_t));
  232. system_oiltank.valid = 0;
  233. system_oiltank.current = 0;
  234. return 0;
  235. }