/* * msp_OBD.c * * Created on: Oct 26, 2023 * Author: shiya * 主要功能: * 1.配置跳转进入bootloader * 2.周期性上传GV * ——每2ms上传一帧报文 * ——循环上传报文 * 3.配置GV上传选项 * ——可选择上传那一个元素 * ——默认不上传 * 4.设置CV的值(响应CAN总线)(单个写入) * ——判断与之前数值不同,就写入到eeprom中 * 5.读取CV的值(响应CAN总线)(单个) * 6.配置CV的值全部更新入EEPROM * 8.从EEPROM读取CV的值 * ——在GF_MSP_OBD_Init()中执行读取更新 * 1. 0x110, * —— 1字节0x55,复位重新尝试进入bootloader; * 2. 0x120,配置CV的值 * —— 1-2字节,对应 CV Index,uint16_t * —— 3-6字节,对应CV的值 * 3. 0x121,请求读取CV的值 * —— 1-2字节,对应 CV Index,uint16_t * 4. 0x122,返回CV的值 * —— 1-2字节,对应 CV Index,uint16_t * —— 3-6字节,对应CV的值 * 5. 0x130,配置GV的输出 * —— 1-2字节,对应 GV Index,uint16_t * —— 3-4字节,对应 GV Index的长度,设置连续的GV输出 * —— 5 字节,0为发送禁止,1为单次查询,2为周期性查询 uint8_t * 6. 0x132,输出GV的值 * —— 1-2字节,对应 GV Index,uint16_t * —— 3-6字节,对应GV的值 */ #include "MSP/msp_OBD.h" #include "BHBF_ROBOT.h" #include #define DF_MSP_OBD_GV_Num (sizeof(GV)/4) //GV元素个数 #define DF_MSP_OBD_CV_Num (sizeof(CV)/4) //CV元素个数 #define DF_MSP_FDCAN_ID_Boot 0x110 #define DF_MSP_FDCAN_ID_SetCV 0x120 #define DF_MSP_FDCAN_ID_ReadCV 0x121 #define DF_MSP_FDCAN_ID_SendCV 0x122 #define DF_MSP_FDCAN_ID_ConfigGV 0x130 #define DF_MSP_FDCAN_ID_SendGV 0x132 uint32_t V_MSP_OBD_GVsend_Index; //循环上传GV的索引 uint8_t V_MSP_OBD_GVsend_EN[DF_MSP_OBD_GV_Num]; //是否上传对应的GV变量 uint8_t V_MSP_OBD_FDCAN_CH; int32_t* P_MSP_OBD_Point_to_GV; int32_t* P_MSP_OBD_Point_to_CV; uint8_t MSP_OBD_Set_CV(uint32_t CV_Index,int32_t CV_Value); uint8_t MSP_OBD_EE_Read_CV(uint32_t CV_Index,int32_t* CV_Value); uint8_t MSP_OBD_EE_Write_CV(uint32_t CV_Index,int32_t CV_Value); uint8_t MSP_OBD_CV_InitEE(void); uint8_t MSP_OBD_CV_Update(void); void MSP_OBD_Jump_Bootloader(void) { HAL_NVIC_SystemReset(); } uint8_t MSP_OBD_EE_Read_CV(uint32_t CV_Index,int32_t* CV_Value) { uint8_t _u8array[4]; int32_t* _i32point; if(GF_BSP_EEPROM_ReadBytes(_u8array, CV_Index*4, 4) != 1) { return 0; } _i32point = (int32_t*)&_u8array; *CV_Value = *_i32point; return 1; } uint8_t MSP_OBD_EE_Write_CV(uint32_t CV_Index,int32_t CV_Value) { uint8_t* _u8array; _u8array=(uint8_t*)(&P_MSP_OBD_Point_to_CV[CV_Index]); return(GF_BSP_EEPROM_WriteBytes(_u8array, CV_Index*4, 4)); } uint8_t GF_MSP_OBD_Init(uint8_t FDCAN_CH) { V_MSP_OBD_FDCAN_CH = FDCAN_CH; P_MSP_OBD_Point_to_GV = (int32_t*)&GV; P_MSP_OBD_Point_to_CV = (int32_t*)&CV; memset(&V_MSP_OBD_GVsend_EN, 0, DF_MSP_OBD_GV_Num); V_MSP_OBD_GVsend_Index=0; if(GF_BSP_EEPROM_CheckOK() != 1) { return 0; } if(MSP_OBD_CV_Update() != 1) { return 0; } if(GF_BSP_Interrupt_Add_CallBack(DF_BSP_InterCall_FDCAN2_RxFifo0Callback,GF_MSP_OBD_Rx_CallBack) !=1) { return 0; } return 1; } //设置CV的值,如果不同就写入到eeprom中 uint8_t MSP_OBD_Set_CV(uint32_t CV_Index,int32_t CV_Value) { if(CV_Index >= DF_MSP_OBD_CV_Num) { return 0; } if(P_MSP_OBD_Point_to_CV[CV_Index] != CV_Value) { P_MSP_OBD_Point_to_CV[CV_Index] = CV_Value; return(MSP_OBD_EE_Write_CV(CV_Index,CV_Value)); } return 1; } //配置CV的值全部更新入EEPROM,仅首次使用时需要 uint8_t MSP_OBD_CV_InitEE(void) { for(uint8_t i=0; i>8); _Tbuf[4] = (uint8_t)(P_MSP_OBD_Point_to_CV[_Index]>>16); _Tbuf[5] = (uint8_t)(P_MSP_OBD_Point_to_CV[_Index]>>24); GF_BSP_FDCAN_Senddata(V_MSP_OBD_FDCAN_CH, DF_MSP_FDCAN_ID_SendCV, 6, _Tbuf); } break; case DF_MSP_FDCAN_ID_ConfigGV: _Index = (((uint16_t)_Rbuf[1])<<8) + _Rbuf[0]; _Set_length = (((uint16_t)_Rbuf[3])<<8) + _Rbuf[2]; if(_Index < DF_MSP_OBD_GV_Num) { if(_Index + _Set_length > DF_MSP_OBD_GV_Num) { _Set_length = DF_MSP_OBD_GV_Num - _Index; } for(uint16_t i=0;i<_Set_length;i++) { V_MSP_OBD_GVsend_EN[_Index+i]=_Rbuf[4]; } } break; default: break; } } } // //2ms执行一次,周期上传GV数值 void GF_MSP_OBD_Run_Timer(void) { uint8_t _Tbuf[8]; uint16_t i; for(i=V_MSP_OBD_GVsend_Index; i>8); _Tbuf[2] = (uint8_t)(P_MSP_OBD_Point_to_GV[i]); _Tbuf[3] = (uint8_t)(P_MSP_OBD_Point_to_GV[i]>>8); _Tbuf[4] = (uint8_t)(P_MSP_OBD_Point_to_GV[i]>>16); _Tbuf[5] = (uint8_t)(P_MSP_OBD_Point_to_GV[i]>>24); GF_BSP_FDCAN_Senddata(V_MSP_OBD_FDCAN_CH, DF_MSP_FDCAN_ID_SendGV, 6, _Tbuf); if(V_MSP_OBD_GVsend_EN[i] == 1) { V_MSP_OBD_GVsend_EN[i] = 0; } i++; break; } } V_MSP_OBD_GVsend_Index = i; if(V_MSP_OBD_GVsend_Index >= DF_MSP_OBD_GV_Num) { V_MSP_OBD_GVsend_Index=0; } }