enviolo_can.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. #include "enviolo_can.h"
  2. #include "can.h"
  3. #include "speed_sensor.h"
  4. #include "motor_control.h"
  5. #include "log_save.h"
  6. #include "can_process.h"
  7. #include "eeprom_24c02.h"
  8. Enviolo_Struct_t CanEnvioloData = {0};
  9. Enviolo_SetVal_Struct_t EnvioloSetData = {0};
  10. Calibration_Struct_t Enviolo_Calibration = {0};
  11. //计算1~9档位对应的变速比,范围为500~1800
  12. const uint16_t Ratio_Table[9] =
  13. {
  14. 500,
  15. 662,
  16. 824,
  17. 986,
  18. 1148,
  19. 1310,
  20. 1472,
  21. 1634,
  22. 1800
  23. };
  24. /******************************************************************************
  25. * @Function: 解析CAN报文,提取OBC发送的报文信息提取需要设置的目标踏频值和档位比例值
  26. * @Discrible: 查看协议文档ID(0X731)-->0X4008的报文
  27. * @Param: Data:需要分析的报文 RetVal:需要设置的值
  28. * @Return: void
  29. * @Others:
  30. ******************************************************************************
  31. * @Recode date version author modify
  32. * ------------------------------------------------------------------
  33. * 20211025 V1.0.0 leechard create
  34. *
  35. *******************************************************************************/
  36. void GetWorkSetVal(uint8_t* Data, Enviolo_SetVal_Struct_t *RetVal, Calibration_Struct_t *Calib)
  37. {
  38. static uint8_t u8Temp = 0;
  39. if(Data[2] == NOTNEED_CALIB)//无需校准
  40. {
  41. if(Data[0] == WORKMODE_AUTO)//自动模式
  42. {
  43. RetVal->u8DesiredGearBoxMode = WORKMODE_AUTO;
  44. RetVal->u16DesiredGearRatio = 0;
  45. RetVal->u16DesiredCanence = Data[1];
  46. }
  47. else if(Data[0] == WORKMODE_MANUAL)//手动模式
  48. {
  49. RetVal->u8DesiredGearBoxMode = WORKMODE_MANUAL;
  50. //根据手动设置的档位计算需要设置的变速比例值
  51. RetVal->u16DesiredGearRatio = (Data[1] == 0)?Ratio_Table[0]:((Data[1]>8)?Ratio_Table[8]:Ratio_Table[Data[1]-1]);
  52. RetVal->u16DesiredCanence = 0;
  53. }
  54. u8Temp = 0;
  55. }
  56. else if(Data[2] == NEED_CALIB)//需要校准
  57. {
  58. RetVal->u8DesiredGearBoxMode = WORKMODE_CALIB;
  59. if(u8Temp == 0)
  60. {
  61. Calib->u8CalibrationCmdToEnviolo = 1;
  62. u8Temp = 1;
  63. }
  64. }
  65. }
  66. /******************************************************************************
  67. * @Function: 200MS发送报文到enviolo,默认5min不发送报文则enviolo自动休眠
  68. * @Discrible: 通过工作模式设置相应的值到enviolo
  69. * @Param:
  70. * @Return: void
  71. * @Others:
  72. ******************************************************************************
  73. * @Recode date version author modify
  74. * ------------------------------------------------------------------
  75. * 20211025 V1.0.0 leechard create
  76. *
  77. *******************************************************************************/
  78. void sendDataToEnviolo(Enviolo_SetVal_Struct_t *st_SendData, Calibration_Struct_t *st_Calib)
  79. {
  80. static uint8_t u8SendCnt = 0;
  81. uint8_t sendbuf[8]={0};
  82. //发送100次控制指令后再发送一次配置指令
  83. u8SendCnt++;
  84. if(u8SendCnt >= 100)
  85. {
  86. u8SendCnt = 0;
  87. CanEnvioloData.u8SendConfigDataToEnviolo = SEND_CONFIG;
  88. }
  89. //参数配置只发送一次
  90. if(CanEnvioloData.u8SendConfigDataToEnviolo == SEND_CONFIG)
  91. {
  92. if((st_SendData->u8DesiredGearBoxMode == WORKMODE_MANUAL)||(st_SendData->u8DesiredGearBoxMode == WORKMODE_AUTO))
  93. {
  94. GetParamFromEEprom_24C02(&I2C_Handle_EEPROM, EEPROM_24C02_ADDR_CONFIG_PARAM1, sizeof(MC_ConfigParam1), (uint8_t*)&MC_ConfigParam1.GasCtrlMode_Flag);
  95. sendbuf[0] = MC_ConfigParam1.TeethNum_F*2.4; //DU_Front_Chainring
  96. sendbuf[1] = MC_ConfigParam1.TeethNum_B; //DU_RearSprocket
  97. sendbuf[2] = DU_CADENCE_LOWLIMIT; //DU_Cadence_LowLimit
  98. sendbuf[3] = DU_CADENCE_HIGHLIMIT; //DU_Cadence_HighLimit
  99. sendbuf[4] = 0x00; //Reserved
  100. sendbuf[5] = (MC_ConfigParam1.WheelSize > 100)?(MC_ConfigParam1.WheelSize - 100):0;//
  101. sendbuf[6] = DU_SLEEPTIME; //DU_SleepTime
  102. sendbuf[7] = 0x00; //Reserved
  103. CAN_SendData(ID_ENVIOLO_CONFIG, sendbuf, sizeof(sendbuf));
  104. CanEnvioloData.u8SendConfigDataToEnviolo = SEND_DATA;
  105. }
  106. }
  107. else if(CanEnvioloData.u8SendConfigDataToEnviolo == SEND_DATA)
  108. {
  109. if((MC_ControlCode.GearSt == MC_GearSt_WALK)||(MC_ControlCode.GearSt == MC_GearSt_OFF))//推行模式和0档位将档位设置为最低档
  110. {
  111. sendbuf[0] = WORKMODE_MANUAL;
  112. sendbuf[1] = (uint8_t)(Ratio_Table[0]>>8);
  113. sendbuf[2] = (uint8_t)(Ratio_Table[0]);
  114. sendbuf[3] = 0X00;
  115. sendbuf[4] = 0X00;
  116. CAN_SendData(ID_ENVIOLO_CONTROL, sendbuf, sizeof(sendbuf));
  117. }
  118. else
  119. {
  120. if(st_SendData->u8DesiredGearBoxMode == WORKMODE_MANUAL)//如果是手动模式
  121. {
  122. sendbuf[0] = st_SendData->u8DesiredGearBoxMode;
  123. sendbuf[1] = (uint8_t)(st_SendData->u16DesiredGearRatio>>8);
  124. sendbuf[2] = (uint8_t)(st_SendData->u16DesiredGearRatio);
  125. sendbuf[3] = 0X00;
  126. sendbuf[4] = 0X00;
  127. CAN_SendData(ID_ENVIOLO_CONTROL,sendbuf,sizeof(sendbuf));
  128. }
  129. else if(st_SendData->u8DesiredGearBoxMode == WORKMODE_AUTO)//如果是自动模式
  130. {
  131. sendbuf[0] = st_SendData->u8DesiredGearBoxMode;
  132. sendbuf[1] = 0X00;
  133. sendbuf[2] = 0X00;
  134. sendbuf[3] = (uint8_t)(st_SendData->u16DesiredCanence>>8);
  135. sendbuf[4] = (uint8_t)(st_SendData->u16DesiredCanence);
  136. CAN_SendData(ID_ENVIOLO_CONTROL,sendbuf,sizeof(sendbuf));
  137. }
  138. else if(st_SendData->u8DesiredGearBoxMode == WORKMODE_CALIB)//校准模式
  139. {
  140. if(st_Calib->u8CalibrationCmdToEnviolo == 1)//第一次关闭自动变速器
  141. {
  142. sendbuf[0] = 0X00;
  143. CAN_SendData(ID_ENVIOLO_CONTROL,sendbuf,sizeof(sendbuf));
  144. st_Calib->u8CalibrationCmdToEnviolo++;
  145. }
  146. else if(st_Calib->u8CalibrationCmdToEnviolo == 2)//第二次让enviolo进入到校准指令中
  147. {
  148. sendbuf[0] = 0X08;
  149. CAN_SendData(ID_ENVIOLO_CONTROL,sendbuf,sizeof(sendbuf));
  150. st_Calib->u8CalibrationCmdToEnviolo++;
  151. }
  152. else if(st_Calib->u8CalibrationCmdToEnviolo == 3)//第三次使能enviolo的ACTIVE模式
  153. {
  154. sendbuf[0] = 0X01;//开启变速器的数据报文模式做监听 Active
  155. CAN_SendData(ID_ENVIOLO_CONTROL,sendbuf,sizeof(sendbuf));
  156. st_Calib->u8CalibrationCmdToEnviolo++;
  157. st_Calib->u8CalibrationCmdToOBC = DIS_PEDALLING;//让ui显示校准中
  158. }
  159. }
  160. else
  161. {
  162. sendbuf[0] = WORKMODE_OFF; //关闭
  163. sendbuf[1] = 0X00;
  164. sendbuf[2] = 0X00;
  165. sendbuf[3] = 0X00;
  166. sendbuf[4] = 0X00;
  167. CAN_SendData(ID_ENVIOLO_CONTROL,sendbuf,sizeof(sendbuf));
  168. }
  169. }
  170. }
  171. }
  172. /******************************************************************************
  173. * @Function: 200MS发送报文到OBC
  174. * @Discrible: 通过报文的设置让enviolo进入到不同的UI界面
  175. * @Param:
  176. * @Return: void
  177. * @Others:
  178. ******************************************************************************
  179. * @Recode date version author modify
  180. * ------------------------------------------------------------------
  181. * 20211025 V1.0.0 leechard create
  182. *
  183. *******************************************************************************/
  184. void sendDataToOBC(uint8_t u8Step)
  185. {
  186. static uint8_t u8OldStep = 0;
  187. uint8_t sendbuf[8]={MC_ConfigParam1.WheelSize,MC_ConfigParam1.StarModel,MC_ConfigParam1.SpeedLimit,MC_ConfigParam1.WheelSizeAdj,0X00,0X00,0X00,0X00};//轮胎默认周长,启动模式,限速值,轮胎微调值
  188. if(u8OldStep != u8Step)
  189. {
  190. switch(u8Step)
  191. {
  192. case 1:
  193. {
  194. sendbuf[4] = 0x01;//UI界面提示需要校准
  195. break;
  196. }
  197. case 2:
  198. {
  199. sendbuf[4] = 0x02;//UI界面显示校准中
  200. break;
  201. }
  202. case 3:
  203. {
  204. sendbuf[4] = 0x00;//UI界面显示校准完成
  205. break;
  206. }
  207. default:
  208. {
  209. break;
  210. }
  211. }
  212. u8OldStep = u8Step;
  213. SendData(ID_MC_TO_PBU, MODE_REPORT, 0x5408, sendbuf);
  214. }
  215. }
  216. /******************************************************************************
  217. * @Function: 收到关机指令则发送关闭enviolo的报文
  218. * @Discrible: 关机前最后一帧报文
  219. * @Param:
  220. * @Return: void
  221. * @Others:
  222. ******************************************************************************
  223. * @Recode date version author modify
  224. * ------------------------------------------------------------------
  225. * 20211025 V1.0.0 leechard create
  226. *
  227. *******************************************************************************/
  228. void sendDataToEnvioloPwroff(void)
  229. {
  230. uint8_t sendbuf[8]={0};
  231. CAN_SendData(ID_ENVIOLO_CONTROL,sendbuf,8);
  232. }
  233. /******************************************************************************
  234. * @Function: 解析enviolo发过来的报文
  235. * @Discrible: 解析8字节报文数据
  236. * @Param: 8字节报文数据
  237. * @Return: void
  238. * @Others:
  239. ******************************************************************************
  240. * @Recode date version author modify
  241. * ------------------------------------------------------------------
  242. * 20211203 V1.0.0 leechard create
  243. *
  244. *******************************************************************************/
  245. void Slot_EnvioloData(uint8_t *u8Data, Calibration_Struct_t *Calib)
  246. {
  247. CanEnvioloData.u8Get_Gear_Pedal_RPM = u8Data[0]; //反馈的踏频值 cadence
  248. CanEnvioloData.u8Get_Gear_CVP_Actuel_Ratio = u8Data[1]; //实际的档位值 1bit = 0.1ratio
  249. CanEnvioloData.u16Get_Gear_Vehicle_Speed = (u8Data[2])*5; //当前速度 乘以0.5 eg:50=25km/h 文档协议单位为0.1,故乘以5
  250. CanEnvioloData.flGet_Gear_Battery_Voltage = (u8Data[3])*0.25; //当前电压值 乘以0.25 eg:102=25.5km/h
  251. CanEnvioloData.u16Get_Gear_Wheel_RPM = (uint16_t)(u8Data[4]<<8)|(uint16_t)(u8Data[5]); //车轮转速 需要设置车子周长
  252. CanEnvioloData.u16CalibrationVal = (uint16_t)(u8Data[6]<<8)|(uint16_t)(u8Data[7]); //获取是否需要校准
  253. //以下为校准信息的判断
  254. if((CanEnvioloData.u16CalibrationVal&0X1000) == 0X1000) //bit51:Calibration Needed
  255. {
  256. Calib->u8CalibrationCmdToOBC = DIS_PEDAL;//需要校准
  257. }
  258. else if((CanEnvioloData.u16CalibrationVal&0X2000) == 0X2000)//校准完成 //bit50:Calibration Success
  259. {
  260. Calib->u8CalibrationCmdToOBC = DIS_SUCCESS;//校准成功并完成
  261. Calib->u8CalibrationCmdToEnviolo = 0;
  262. Calib->u8CalibrationCmdToOBC = 0;
  263. }
  264. if(MC_SpeedSensorData.IsStopFlag == TRUE)
  265. {
  266. MC_SpeedSensorData.IsStopFlag = FALSE;
  267. }
  268. CanEnvioloData.u16Timeout_Communication = 0;
  269. }
  270. /******************************************************************************
  271. * @Function: enviolo通信检测,超时则报错
  272. * @Discrible:
  273. * @Param:
  274. * @Return: void
  275. * @Others:
  276. ******************************************************************************
  277. * @Recode date version author modify
  278. * ------------------------------------------------------------------
  279. * 20211203 V1.0.0 leechard create
  280. *
  281. *******************************************************************************/
  282. void MC_Fault_Enviolo_SpeedSensor_Process(MC_ErrorCode_Struct_t* p_MC_ErrorCode)
  283. {
  284. if(p_MC_ErrorCode->ERROR_Bit.Fault_SpeedSensor == 0)
  285. {
  286. if(CanEnvioloData.u16Timeout_Communication >= COMMUNICATION_TIMEOUT)
  287. {
  288. p_MC_ErrorCode->ERROR_Bit.Fault_SpeedSensor = 1;
  289. //记录故障日志
  290. MC_ErrorLogSaveInfo.NotesInfo1 = 3;
  291. ErrorLogSave_Update(&MC_ErrorLogSaveInfo);
  292. IsErrorLogSaveInfoUpdateFlag = TRUE;
  293. //存储故障次数
  294. MC_RunLog1.SPS_FaultCnt++;
  295. RunLogSaveIndex = 1;
  296. }
  297. }
  298. }