protocol_old.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. #include <string.h>
  2. #include "app/sox/soc.h"
  3. #include "app/sox/measure.h"
  4. #include "app/sox/measure_task.h"
  5. #include "app/sox/health.h"
  6. #include "app/sox/state.h"
  7. #include "app/sox/iostate.h"
  8. #include "bsp/gpio.h"
  9. #include "bsp/ml5238.h"
  10. #include "app/nv_storage.h"
  11. #include "libs/logger.h"
  12. #include "bsp/uart.h"
  13. #include "protocol_old.h"
  14. #include "pcba_test.h"
  15. static uart_enum_t current_uart = SHARK_UART0;
  16. extern char* bsp_get_fversion(void);
  17. uint16_t _checksum(uint8_t *data, uint16_t size) {
  18. uint32_t checksum;
  19. if((NULL == data) || (0 == size)) {
  20. return 0;
  21. }
  22. checksum = 0;
  23. while(size>1) {
  24. checksum += *(uint16_t*)data;
  25. data += 2;
  26. size -= 2;
  27. }
  28. if(size>0) {
  29. checksum += *data;
  30. }
  31. while(checksum>>16) {
  32. checksum = (checksum&0xFFFF)+(checksum>>16);
  33. }
  34. return (uint16_t)~checksum;
  35. }
  36. static int get_response_data(uint8_t *data, uint8_t operate, uint8_t result){
  37. comm_head_t *head = (comm_head_t *)data;
  38. head->size = sizeof(comm_head_t);
  39. head->type = bms_state_get()->bms_addr;
  40. head->dir = 0x16;
  41. head->bStatus = 1;
  42. head->cmd = 0x10;
  43. head->protocol = 'C';
  44. head->checksum = 0;
  45. comm_response_t *response = (comm_response_t *)head->data;
  46. response->remain_miles= 0; //剩余里程
  47. response->capacity = get_soc()->capacity;
  48. response->remain_charger_time= soc_get_charger_remain_time()/6; //10分之1小时单位
  49. response->is_chargering = bms_state_get()->charging;
  50. response->load_current = measure_value()->load_current;
  51. response->pack_voltage = bms_state_get()->pack_voltage;
  52. response->max_temp = -100;
  53. for (int i = 0; i < PACK_TEMPS_NUM; i++){
  54. if (response->max_temp < measure_value()->pack_temp[i]){
  55. response->max_temp = measure_value()->pack_temp[i];
  56. }
  57. }
  58. response->health_state = ((uint16_t)bms_health()->i_status) | (bms_health()->sigle_cell_lower_voltage << 1);
  59. if (bms_is_ps_charger_in()) {
  60. response->health_state |= (bms_health()->lower_temp_deny_charger << 12 | bms_health()->over_temp_deny_charger << 14);
  61. }
  62. response->balance_mask = 0x0;
  63. response->misc_status = (ml5238_is_discharging() << 1) | (ml5238_is_charging() << 2);
  64. response->misc_status |= (AUX_VOL_IS_OPEN() << 3) |(io_state()->aux_lock_detect << 5);
  65. response->misc_status |= ((get_soc()->capacity==100) << 4) | (((get_soc()->flags & SOC_FLAG_CALIBRATED) == 0) << 6);
  66. response->misc_status |= io_state()->charger_detect_irq;
  67. response->result = (operate << 4) | result;
  68. head->size += sizeof(comm_response_t);
  69. if (operate == OP_READ_INFO){
  70. uint8_t sn[32];
  71. int sn_len = nv_read_sn(sn, sizeof(sn));
  72. if (sn_len <= 0){
  73. sn[0] = 'B';
  74. memset(sn + 1, '0', sizeof(sn) - 1);
  75. sn_len = 18;
  76. }
  77. memcpy(&data[head->size], sn, sn_len);
  78. head->size += sn_len;
  79. strcpy((char *)&data[head->size], bsp_get_fversion());
  80. head->size += strlen(bsp_get_fversion());
  81. }else if (operate == OP_ALARM_TIMES){
  82. memset(&data[head->size], 0, sizeof(times_response_t));
  83. times_response_t *resp = (times_response_t *)&data[head->size];
  84. resp->charger_cycle = soc_get_cycle();
  85. resp->soh = soc_get_soh();
  86. head->size += sizeof(times_response_t);
  87. }else if (operate == OP_CELL_VOL){
  88. data[head->size ++] = CELLS_NUM;
  89. for (int i = 0; i <CELLS_NUM; i++){
  90. data[head->size ++] = (uint8_t)measure_value()->cell_vol[i];
  91. data[head->size ++] = (uint8_t)(measure_value()->cell_vol[i] >> 8);
  92. }
  93. }else if (operate == OP_TEMP_OTHER){
  94. for (int i = 0; i < PACK_TEMPS_NUM; i++){
  95. data[head->size ++] = measure_value()->pack_temp[i];
  96. }
  97. data[head->size ++] = (ml5238_is_charging() << 0) | (ml5238_is_discharging() << 1);
  98. }else if (operate == OP_READ_DETECT){
  99. data[head->size++] = IS_HALL1_DETECTED() | IS_HALL2_DETECTED() << 1 | IS_CHARGER_IN() << 2;
  100. data[head->size++] = IS_DCDC_POWER_GOOD() | AUX_VOL_IS_OPEN() << 1 | IS_AUX_VOL_LOCKED() << 2;
  101. }else if (operate == OP_AGING_TEMPS) {
  102. int8_t *idata = (int8_t *)data;
  103. data[head->size ++] = bms_state_get()->agint_cost_time/60; //分钟
  104. for (int i = 0; i < PACK_TEMPS_NUM; i++){
  105. idata[head->size ++] = (int8_t)(bms_state_get()->aging_start_temp[i]);
  106. }
  107. for (int i = 0; i < PACK_TEMPS_NUM; i++){
  108. idata[head->size ++] = (int8_t)(bms_state_get()->aging_max_temp[i]);
  109. }
  110. }
  111. head->checksum = _checksum(data, head->size);
  112. return head->size;
  113. }
  114. extern u32 uart_old_prot;
  115. extern u64 uart_frame_time;
  116. static int protocol_old_process_binary(uart_enum_t uart_no, uint8_t *data, int len){
  117. current_uart = uart_no;
  118. comm_head_t *head = (comm_head_t *)data;
  119. if (/*head->type != bms_state_get()->bms_addr || */head->dir != 0x16 || head->bStatus == 1 || head->size < sizeof(comm_head_t)){
  120. return -1;
  121. }
  122. uint16_t checksum = head->checksum;
  123. head->checksum = 0;
  124. if (checksum != _checksum(data, len)){
  125. return -1;
  126. }
  127. uart_old_prot ++;
  128. uart_frame_time = shark_get_mseconds();
  129. data = head->data;
  130. data += 6;
  131. uint8_t operate = data[0];
  132. uint8_t ps_charger = data[1];
  133. bms_set_ps_charger_in(1, (ps_charger == CW_CHE_SHANG_CHARGER || ps_charger == CW_CHONG_DIAN_ZUO));
  134. if ((ps_charger == CW_CHE_SHANG_CHARGER) || (ps_charger == CW_CHE_SHANG_NO_CHARGER)) {
  135. bms_work_mode_set(WORK_MODE_AGING_TEST, 0);
  136. }
  137. data += 1;
  138. uint8_t result = 1;
  139. if (operate == OP_OPEN_FET){
  140. if (data[8] == 0x01) {
  141. bms_state_get()->user_request = USER_REQUEST_PENDING | USER_REQUEST_DISCHARGER_ON|USER_REQUEST_CHARGER_OFF;
  142. }else if (data[8] == 0x02) {
  143. bms_state_get()->user_request = USER_REQUEST_PENDING | USER_REQUEST_DISCHARGER_OFF|USER_REQUEST_CHARGER_ON;
  144. }else if (data[8] == 0x03) {
  145. bms_state_get()->user_request = USER_REQUEST_PENDING | USER_REQUEST_DISCHARGER_ON|USER_REQUEST_CHARGER_ON;
  146. }else if (data[8] == 0x0){
  147. bms_state_get()->user_request = USER_REQUEST_PENDING | USER_REQUEST_SMALLCURRENT_OFF|USER_REQUEST_DISCHARGER_OFF|USER_REQUEST_CHARGER_OFF;
  148. }else if (data[8] == 0x04) {
  149. bms_state_get()->user_request = USER_REQUEST_PENDING | USER_REQUEST_SMALLCURRENT_ON;
  150. }else {
  151. result = 0;
  152. }
  153. }else if (operate == OP_WRITE_SN){
  154. if (data[8] == 1) {
  155. result = nv_save_sn(&data[9], 18) <= 0?1:0;
  156. }
  157. }
  158. uint8_t response_data[256];
  159. uint16_t response_len = get_response_data(response_data, operate, result);
  160. if (response_len <= 0){
  161. return -1;
  162. }
  163. set_log_all(L_disable);
  164. shark_uart_write_bytes(current_uart, response_data, response_len);
  165. return 0;
  166. }
  167. void protocol_old_recv_frame(uart_enum_t uart_no, uint8_t *data, int len){
  168. if (protocol_old_process_binary(uart_no, data, len) == 0){
  169. return;
  170. }
  171. if (memcmp(data, "mode", 4) == 0){
  172. set_log_all(L_disable);
  173. if (memcmp(data + 4, "laohua", 6) == 0){
  174. bms_work_mode_set(WORK_MODE_AGING_TEST, 1);
  175. bms_state_get()->user_request = USER_REQUEST_PENDING | USER_REQUEST_SMALLCURRENT_OFF | USER_REQUEST_DISCHARGER_ON|USER_REQUEST_CHARGER_ON;
  176. printf("laohua OK!\n");
  177. }else if (memcmp(data + 4, "tuichu", 6) == 0){
  178. if (bms_work_is_aging_test() || bms_work_is_pcba_test() || bms_work_is_pack_test()){
  179. bms_work_mode_set(WORK_MODE_AGING_TEST, 0);
  180. bms_state_get()->user_request = USER_REQUEST_PENDING | USER_REQUEST_SMALLCURRENT_ON | USER_REQUEST_DISCHARGER_OFF | USER_REQUEST_CHARGER_OFF;
  181. printf("tuichu OK!\n");
  182. }
  183. }else if (memcmp(data + 4, "ceshi", 5) == 0) {
  184. bms_work_mode_set(WORK_MODE_PCBA_TEST, 1);
  185. printf("ceshi success!\n");
  186. }
  187. }else if (bms_work_is_pcba_test() && data[0] == 0xFE && data[1] == 0xFE){
  188. uint8_t response[16];
  189. int resp_len = pcba_test(data, len, response);
  190. if (resp_len > 0) {
  191. shark_uart_write_bytes(current_uart, response, resp_len);
  192. }
  193. }
  194. }