123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313 |
- #include "soft_okcell.h"
- #include "string.h"
- #include "common.h"
- #include "crc.h"
- #include "soft_can.h"
- #include "soft_crc.h"
- //在数组中array查找是否存在字符串str
- //不能使用strstr函数,数组中存在'\0'的话会被结束
- int findStrInArray(uint8_t *array, int aLen, const char *str);
- uint8_t group_num = 0; //电池组数
- #define RESET_OKIDCODE_DELAY (3)
- unsigned char okcell_sha1_out[20] = {0};
- //结构体指针类型
- _OKCELL_DEVICE okcell_device1 = {.Okcell_Link.connect_status = COMP_NOEXIST,
- .Okcell_get_s = false,
- .okcell_inf.cell_D0.cell_d0[6] = 0},
- okcell_device2 = {.Okcell_Link.connect_status = COMP_NOEXIST,
- .Okcell_get_s = false,
- .okcell_inf.cell_D0.cell_d0[6] = 0};
- void OkcellCanRecvHookFunction(uint32_t cellCanID, uint8_t data[], uint8_t len)
- {
- _OKCELL_DEVICE *OKptr = NULL;
- //添加兼容两组电池
- static uint8_t OKIdCode1counts = 0,OKIdCode2counts = 0;
- //判断是哪个电池的ID,通过ID来区分电池。并支持飞控不断电更换电池
- if(cellCanID != okcell_device1.deviceCanID && cellCanID != okcell_device2.deviceCanID)
- {
- //分配给1号结构体
- if(OKIdCode1counts == 0){
- OKIdCode1counts = RESET_OKIDCODE_DELAY;
-
- OKptr = &okcell_device1;
- OKptr->deviceCanID = cellCanID;
- group_num = 1;
- }
- //分配给2号结构体
- else if(OKIdCode2counts == 0) {
- OKIdCode2counts = RESET_OKIDCODE_DELAY;
-
- OKptr = &okcell_device2;
- OKptr->deviceCanID = cellCanID;
- group_num = 2;
- }
- //不分配结构体
- else{
- OKIdCode1counts>0 ? OKIdCode1counts-- : OKIdCode1counts;
- OKIdCode2counts>0 ? OKIdCode2counts-- : OKIdCode2counts;
- }
- }
- else if(cellCanID == okcell_device1.deviceCanID)
- {
- OKIdCode1counts = RESET_OKIDCODE_DELAY;
-
- OKptr = &okcell_device1;
- OKptr->deviceCanID = cellCanID;
- }
- else if(cellCanID == okcell_device2.deviceCanID)
- {
- OKIdCode2counts = RESET_OKIDCODE_DELAY;
-
- OKptr = &okcell_device2;
- OKptr->deviceCanID = cellCanID;
- }
-
-
- //如果指针找到了存放数据的结构体
- if(OKptr != NULL)
- {
- //找到开头,开始接收
- //strncmp比较字符串,遇到'\0'会结束,所以不适合用字数组比较
- if(memcmp(data,"ZFKJ",4) == 0){
- OKptr->Okcell_recv_index = 0;
- OKptr->Okcell_get_s = true;
- }
- //溢出检测
- if(OKptr->Okcell_recv_index + len > OKCELL_MAXLEN)
- {
- memset(OKptr->Okcell_recv_buf,0,OKptr->Okcell_recv_index);
- OKptr->Okcell_recv_index = 0;
- OKptr->Okcell_get_s = false;
- }
-
- //接收到起始标志后开始存数组
- if(OKptr->Okcell_get_s == true){
- //复制数据
- memcpy(&OKptr->Okcell_recv_buf[OKptr->Okcell_recv_index], data, len);
- OKptr->Okcell_recv_index += len;
- }
-
- //找到结尾,开始解析,不能用strstr
- if(OKptr->Okcell_get_s == true && findStrInArray(OKptr->Okcell_recv_buf, OKptr->Okcell_recv_index, "END") != 0)
- {
- OKptr->Okcell_get_s = false;
-
- unsigned char loadflag = OKptr->Okcell_recv_buf[7];
- //负载标识为固定的OxBB
- if(loadflag == 0xBB)
- {
- unsigned char cellLoadLen = OKptr->Okcell_recv_buf[6];
-
- //避免错误数据造成的数组溢出
- if(cellLoadLen < OKCELL_MAXLEN-9)
- {
- unsigned int cellCheck = OKptr->Okcell_recv_buf[8+cellLoadLen]*256 + OKptr->Okcell_recv_buf[9+cellLoadLen];
- //校验通过,测试没通过
- if(((crc_ccitt(&OKptr->Okcell_recv_buf[8], cellLoadLen))&0xffff) == cellCheck)
- {
- unsigned short cellCmd = (OKptr->Okcell_recv_buf[4]<<8) + OKptr->Okcell_recv_buf[5];
-
- OKptr->Okcell_Link.connect_status = COMP_NORMAL;
-
- //用于判断电池波特率锁定,实测只要给电池发送数据,电池收到后就会锁定波特率
- //由于锁定波特率缺少反馈应答,5s内收到多于10包正确的数据则认为波特率锁定成功。
- if(OKptr->cell_bps_lock_success == false)
- {
- OKptr->recv_celldata_counts++;
- if(OKptr->recv_celldata_counts == 1){
- OKptr->recv_celldata_time = HAL_GetTick();
- }
- else if(OKptr->recv_celldata_counts >= 10)
- {
- OKptr->recv_celldata_counts = 0;
- uint32_t timeperiod = HAL_GetTick() - OKptr->recv_celldata_time;
- if(timeperiod < 5000000)
- {
- OKptr->cell_bps_lock_success = true;
- }
- }
- }
-
- //更新电池数据到来时间
- OKptr->Okcell_Link.recv_time = HAL_GetTick();
-
- switch(cellCmd)
- {
- case 0x0000:
- //stm32为小段模式,OKCELL发送过来的数据为大端模式,不能使用memcpy
- //memcpy(&cell_D0,&Okcell_recv_buf[8],cellLoadLen);
- //避免电池厂家私自增加协议造成的数组溢出
- if(cellLoadLen <= sizeof(_CELL_D0))
- {
- for(unsigned char i=0; i<cellLoadLen/2; i++)
- {
- OKptr->okcell_inf.cell_D0.cell_d0[i] = (OKptr->Okcell_recv_buf[8 + i*2] << 8) + OKptr->Okcell_recv_buf[9 + i*2];
- }
- }
- break;
- case 0x0300:
- //cell_inf1.cell_D3.cell_d3[4] = (Okcell_recv_buf[16] << 8) + Okcell_recv_buf[17];
- //避免电池厂家私自增加协议造成的数组溢出
- if(cellLoadLen <= sizeof(_CELL_D3))
- {
- for(unsigned char i=0; i<cellLoadLen/2; i++)
- {
- OKptr->okcell_inf.cell_D3.cell_d3[i] = (OKptr->Okcell_recv_buf[8 + i*2] << 8) + OKptr->Okcell_recv_buf[9 + i*2];
- }
- }
- break;
- case 0x8200://SHA1加密文密码查询
- //避免电池厂家私自增加协议造成的数组溢出
- if(cellLoadLen <= sizeof(_CELL_P2))
- {
- for(unsigned char i=0; i<cellLoadLen; i++)
- {
- OKptr->okcell_inf.cell_P2.cell_p2[i] = OKptr->Okcell_recv_buf[8 + i];
- }
- }
-
- if(memcmp(OKptr->okcell_inf.cell_P2.cell_p2, okcell_sha1_out, sizeof(_CELL_P2)) == 0)
- {
- //收到了正确密文
- OKptr->get_cellEncryption = true;
- }
- break;
- case 0x8300://获取电池编号
- OKptr->get_cellNumber = true;
- //避免电池厂家私自增加协议造成的数组溢出
- if(cellLoadLen <= sizeof(_CELL_P3))
- {
- for(uint8_t i=0; i<cellLoadLen; i++)
- {
- OKptr->okcell_inf.cell_P3.cell_p3[i] = OKptr->Okcell_recv_buf[8 + i];
- }
- }
- break;
- default:
- break;
- }
- }
- }
- }
-
- //清理buff
- memset(OKptr->Okcell_recv_buf,0,OKptr->Okcell_recv_index);
-
- //包数完整重新计数
- OKptr->Okcell_recv_index = 0;
- }
- }
- }
- /*
- 上电前10s持续发送数据给智能电池,用于设置通信速率
- */
- struct OkCell_P80 okcell_p80;
- struct OkCell_P82 okcell_p82;
- struct OkCell_P83 okcell_p83;
- uint32_t time_okcell_p80 = 0;
- uint32_t time_okcell_p82 = 0;
- uint32_t time_okcell_p83 = 0;
- bool send_okcell_p80data = false;
- bool send_okcell_p82data = false;
- bool send_okcell_p83data = false;
- void send_msg_to_okcell(void)
- {
- //自动锁定波特率,正方电池开机自动循环500K/1M发送数据。正方电池缺少一个波特率锁定的反馈应答
- //电池开机会自动1M/500k切换波特率给飞控发信息,所以不用用是否连接来判断。
- if(/*okcell_device1.okcell_link_status == COMP_NOEXIST &&*/ send_okcell_p80data == false &&
- okcell_device1.cell_bps_lock_success == false && HAL_GetTick() < 30000 &&
- HAL_GetTick() - time_okcell_p80 > 250)
- {
- time_okcell_p80 = HAL_GetTick();
- okcell_p80.ok_s[0] = 'Z';
- okcell_p80.ok_s[1] = 'F';
- okcell_p80.ok_s[2] = 'K';
- okcell_p80.ok_s[3] = 'J';
-
- okcell_p80.ok_cmd[0] = 0x80;
- okcell_p80.ok_cmd[1] = 0x00;
- okcell_p80.ok_len = 1;
- okcell_p80.ok_flag = 0xbb;
- okcell_p80.ok_data = 0x79;
-
- short OKcellCRC = crc_ccitt((uint8_t *)&okcell_p80.ok_data,okcell_p80.ok_len);
- okcell_p80.ok_crc[0] = (OKcellCRC>>8) & 0xff;
- okcell_p80.ok_crc[1] = OKcellCRC & 0xff;
-
- okcell_p80.ok_e[0] = 'E';
- okcell_p80.ok_e[1] = 'N';
- okcell_p80.ok_e[2] = 'D';
-
- send_okcell_p80data = true;
- }
-
- if(send_okcell_p80data == true){
- send_okcell_p80data =false;
- can_send_msg_normal((unsigned char *)&okcell_p80,sizeof(okcell_p80),CAN_OKCELL_SEND_ID);
- }
-
- if(send_okcell_p82data == true){
- send_okcell_p82data =false;
- can_send_msg_normal((unsigned char *)&okcell_p82,sizeof(okcell_p82),okcell_device1.deviceCanID);
- }
-
-
-
- //获取电池编号
- if(okcell_device1.Okcell_Link.connect_status == COMP_NORMAL && okcell_device1.cell_bps_lock_success == true &&
- okcell_device1.get_cellNumber == false &&
- send_okcell_p83data == false && HAL_GetTick() - time_okcell_p83 > 1000)
- {
- time_okcell_p83 = HAL_GetTick();
-
- okcell_p83.ok_s[0] = 'Z';
- okcell_p83.ok_s[1] = 'F';
- okcell_p83.ok_s[2] = 'K';
- okcell_p83.ok_s[3] = 'J';
-
- okcell_p83.ok_cmd[0] = 0x83;
- okcell_p83.ok_cmd[1] = 0x00;
- okcell_p83.ok_len = 0;
- okcell_p83.ok_flag = 0xbb;
- okcell_p83.ok_crc[0] = 0xff;
- okcell_p83.ok_crc[1] = 0xff;
-
- okcell_p83.ok_e[0] = 'E';
- okcell_p83.ok_e[1] = 'N';
- okcell_p83.ok_e[2] = 'D';
-
- send_okcell_p83data = true;
- }
-
- if(send_okcell_p83data == true){
- send_okcell_p83data =false;
- can_send_msg_normal((unsigned char *)&okcell_p83,sizeof(okcell_p83),okcell_device1.deviceCanID);
- }
- }
|