soft_tattu.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. #include "soft_tattu.h"
  2. #include "string.h"
  3. #include "soft_flash.h"
  4. #include "soft_okcell.h"
  5. #define TATTU_MAXLEN 200
  6. //_TATTU_INFO ttu_inf = {0};
  7. /*
  8. Field Bits Description
  9. Start of transfer 1 See below
  10. End of transfer 1 See below
  11. Toggle bit 1 See below
  12. Transfer ID 5 The transfer ID value
  13. 注意:数据为小端
  14. */
  15. /*
  16. Field Bits Allowed values Description
  17. Priority 5 0-31 默认填最高优先级:0
  18. Message type ID 16 0x1092 查询模式
  19. Service or message 1 0 0x1092----此位为 0;
  20. Source node ID 7 1…127 0 是保留的,代表一个未知的节点;自身的节点 Id;
  21. Destination Node Id 7 1…127 0 是保留的,代表一个未知的节点;对方的节点 Id。
  22. Request not response 1 0 or 1 1 表示该帧是 Request 请求帧;0 表示该帧是 Response 应答帧;
  23. 注意:数据为小端
  24. */
  25. #pragma pack(1)
  26. typedef struct
  27. {
  28. unsigned char canid_prio :5;
  29. unsigned short canid_msgid :16;
  30. unsigned char canid_som :1;
  31. unsigned char canid_srcid :7;
  32. /*unsigned char canid_desid:7;
  33. unsigned char canid_rnr:1;*/
  34. }_TATTU_CANID;
  35. #pragma pack()
  36. _TATTU_DEVICE tattu_device1 = {.Tattu_Link.connect_status = COMP_NOEXIST},
  37. tattu_device2 = {.Tattu_Link.connect_status = COMP_NOEXIST};
  38. void TattuCanRecvHookFunction(uint32_t ttuCanID, uint8_t data[], uint8_t len)
  39. {
  40. //获取数据中的最后一位
  41. _TATTU_DEVICE *taptr = NULL;
  42. uint8_t can_msgid = 0;
  43. can_msgid = ttuCanID & 0x7f;
  44. if(can_msgid == 0x16)
  45. {
  46. taptr = &tattu_device1;
  47. }
  48. else
  49. {
  50. taptr = &tattu_device2;
  51. }
  52. memcpy(&taptr->ttu_tailbyte, &data[len - 1], sizeof(uint8_t));
  53. //找到开头
  54. if(taptr->ttu_tailbyte.tail_start == 1){
  55. taptr->Tattu_recv_index = 0;
  56. taptr->Tattu_get_s = true;
  57. }
  58. //溢出检测
  59. if(taptr->Tattu_recv_index + len > TATTU_MAXLEN)
  60. {
  61. memset(taptr->Tattu_recv_buf,0,taptr->Tattu_recv_index);
  62. taptr->Tattu_recv_index = 0;
  63. taptr->Tattu_get_s = false;
  64. }
  65. //获取到正确的开始位则接收数据
  66. if(taptr->Tattu_get_s == true){
  67. //复制有效数据,最后一个字节不是有效数据
  68. memcpy(&taptr->Tattu_recv_buf[taptr->Tattu_recv_index], data, len-1);
  69. taptr->Tattu_recv_index += (len-1);
  70. }
  71. //找到结尾,开始解析
  72. if(taptr->Tattu_get_s == true && taptr->ttu_tailbyte.tail_end == 1)
  73. {
  74. taptr->Tattu_get_s = false;
  75. taptr->Tattu_Link.connect_status = COMP_NORMAL;
  76. //更新电池数据到来时间
  77. taptr->Tattu_Link.recv_time = HAL_GetTick();
  78. //如果是单帧完整数据
  79. if(taptr->ttu_tailbyte.tail_start == 1 || taptr->Tattu_recv_index <= 7)
  80. {
  81. //单帧数据不需要校验
  82. }
  83. //多帧拼包
  84. else
  85. {
  86. //CRC校验,验证通过,暂不开启
  87. CCITT_CRC16Init(&taptr->Tattu_recv_buf[2],taptr->Tattu_recv_index-2);
  88. if(CCITT_CRC16 == (taptr->Tattu_recv_buf[0] + (taptr->Tattu_recv_buf[1]<<8)))
  89. {
  90. //避免电池单方面增加协议造成溢出,格式电池12s跟14s兼容有问题,飞控自己做处理
  91. //后两个字节是自己添加的用来识别电池串数
  92. if(taptr->Tattu_recv_index-2 <= (sizeof(_TATTU_INFO)-2))
  93. {
  94. //stm32为小段模式,TATTU发送过来的数据为小端模式,可直接使用memcpy
  95. //12S
  96. if(taptr->Tattu_recv_index-2 == (sizeof(_TATTU_INFO)-2-4-16))
  97. {
  98. taptr->ttu_inf.tattu_cnum = 12;
  99. //前12s信息
  100. memcpy(&taptr->ttu_inf,&taptr->Tattu_recv_buf[2],40);
  101. //后边信息
  102. memcpy(&taptr->ttu_inf.tattu_descapa,&taptr->Tattu_recv_buf[40+2],8);
  103. }
  104. //添加序列号后的12s
  105. else if(taptr->Tattu_recv_index-2 == (sizeof(_TATTU_INFO)-2-4))
  106. {
  107. taptr->ttu_inf.tattu_cnum = 12;
  108. //前12s信息
  109. memcpy(&taptr->ttu_inf,&taptr->Tattu_recv_buf[2],40);
  110. //后边信息
  111. memcpy(&taptr->ttu_inf.tattu_descapa,&taptr->Tattu_recv_buf[40+2],24);
  112. }
  113. //14s
  114. else if(taptr->Tattu_recv_index-2 == (sizeof(_TATTU_INFO)-2-16) || taptr->Tattu_recv_index-2 == (sizeof(_TATTU_INFO)-2))
  115. {
  116. taptr->ttu_inf.tattu_cnum = 14;
  117. //14s信息
  118. memcpy(&taptr->ttu_inf,&taptr->Tattu_recv_buf[2],taptr->Tattu_recv_index-2);
  119. }
  120. }else{
  121. //清空电池信息数据
  122. memset(&taptr->ttu_inf, 0, sizeof(_TATTU_INFO));
  123. }
  124. }
  125. }
  126. //清理buff
  127. memset(taptr->Tattu_recv_buf,0,taptr->Tattu_recv_index);
  128. //包数完整重新计数
  129. taptr->Tattu_recv_index = 0;
  130. }
  131. }
  132. /*
  133. 格氏电池的CRC校验
  134. */
  135. #define CRC_CCITT_INIT 0xFFFF
  136. #define CRC_CCITT_POLY 0x1021U
  137. uint16_t CCITT_CRC16 = 0;
  138. void CCITT_CRC16Init(uint8_t const *bytes, uint16_t len)
  139. {
  140. CCITT_CRC16 = CRC_CCITT_INIT;
  141. CCITT_CRC_ARRAY(bytes, len);
  142. }
  143. void CCITT_CRCStep(uint8_t byte)
  144. {
  145. uint32_t j;
  146. CCITT_CRC16 ^= ((uint16_t)byte << 8);
  147. for (j = 0; j < 8; j++)
  148. {
  149. CCITT_CRC16=(CCITT_CRC16 & 0x8000U)?((CCITT_CRC16 << 1) ^ CRC_CCITT_POLY):(CCITT_CRC16 << 1);
  150. }
  151. }
  152. void CCITT_CRC_ARRAY(uint8_t const * bytes, uint16_t len)
  153. {
  154. while (len--) CCITT_CRCStep(*bytes++);
  155. }