/** * @file giant_can.h * @author Ye Jin * @brief giant can protocol * @version 0.1 * @date 2025-01-09 * * @copyright Copyright (c) 2025 * */ /************************************************************************ Beginning of File, do not put anything above here except notes Compiler Directives: *************************************************************************/ #include "can.h" #include "giant_can.h" #include "canAppl.h" #include "string.h" #include "AssistCurve.h" #include "adc.h" #include "power.h" #include "CodePara.h" #include "flash_master.h" /****************************** * * Parameter * ******************************/ GiantStandardDataFrameID_Struct_t stGiantStandardDataFrameID_rx; GiantStandardRemoteFrameID_Struct_t stGiantStandardRemoteFrameID_rx; GiantControlParams_Struct_t stGiantControlParams; CANFrame_Info_Struct_t stCANFrame_InfoRx = {MAXFRAME_SIZE, 0, 0, 0}; CAN_ReceiveFrame_Struct_t stCAN_ReceiveFrame_Buf_Rx[MAXFRAME_SIZE]; /*************************************************************** Function: Description: Call by: Input Variables: N/A Output/Return Variables: N/A Subroutine Call: N/A; Reference: N/A ****************************************************************/ void giant_Init(void) { stGiantControlParams.RidingModeEn = 0; stGiantControlParams.AdjustingMode = AD_CHECKMODE;//check mode stGiantControlParams.WheelCircumference = 2182;//mm stGiantControlParams.StartMode = 2; stGiantControlParams.SpeedLimitation = 4500; ULONG ulAppStatus; FLASH_voReadMoreData(APPLICATIONSTATUS_ADDRESS, (UWORD *)&ulAppStatus, 2);//ULONG-UWORD if(ulAppStatus != 0x5555AAAA) { UWORD app_data[2] = {0xAAAA, 0x5555};//标记为有app FLASH_voWriteMoreData(APPLICATIONSTATUS_ADDRESS, app_data, 2); } } void giant_10msTask(void) { static UBYTE giant_10mscount = 0; if((stGiantControlParams.AdjustingMode == AD_OFFMODE) || (stGiantControlParams.ManualSleepEn) || (stGiantControlParams.AutomaticSleepEn))//Off state { power_stPowStateOut.powerstate = POWER_OFF; power_stPowStateOut.blPowerStartupFlg = FALSE; } if(stGiantControlParams.AdjustingMode == AD_CHECKMODE) { if((cp_ulSystickCnt - ulOBC_ComTimeOutCount) > 1750) { stGiantControlParams.CommSleep = 2; power_stPowStateOut.powerstate = POWER_OFF; power_stPowStateOut.blPowerStartupFlg = FALSE; } else if((cp_ulSystickCnt - ulOBC_ComTimeOutCount) > 1500) { stGiantControlParams.CommSleep = 1; } else { stGiantControlParams.CommSleep = 0; } } else if((stGiantControlParams.AdjustingMode >= AD_SERVICEMODE_S) && (stGiantControlParams.AdjustingMode <= AD_SERVICEMODE_E)) { ulOBC_ComTimeOutCount = cp_ulSystickCnt; stGiantControlParams.CommSleep = 0; } else { if((cp_ulSystickCnt - ulOBC_ComTimeOutCount) > 750) { stGiantControlParams.CommSleep = 2; power_stPowStateOut.powerstate = POWER_OFF; power_stPowStateOut.blPowerStartupFlg = FALSE; } else if((cp_ulSystickCnt - ulOBC_ComTimeOutCount) > 500) { stGiantControlParams.CommSleep = 1; } else { stGiantControlParams.CommSleep = 0; } } giant_10mscount++; if(giant_10mscount >= 5) { giant_10mscount = 0; if(stGiantControlParams.CommSleep == 1) { giant_SendRemote(0x2); } if((power_stPowStateOut.powerstate == POWER_OFF) || ((stGiantControlParams.AdjustingMode >= AD_SERVICEMODE_S) && (stGiantControlParams.AdjustingMode <= AD_CHECKMODE))) { return; } giant_SendDriveChainActiveData(FG_NORMALDATA, 0x0); giant_SendDriveChainActiveData(FG_NORMALDATA, 0x1); giant_SendDriveChainActiveData(FG_NORMALDATA, 0x2); giant_SendDriveChainActiveData(FG_NORMALDATA, 0x3); giant_SendDriveChainActiveData(FG_NORMALDATA, 0x4); giant_SendDriveChainActiveData(FG_NORMALDATA, 0x6); giant_SendDriveChainActiveData(FG_NORMALDATA, 0x7); giant_SendDriveChainActiveData(FG_NORMALDATA, 0x8); giant_SendDriveChainActiveData(FG_NORMALDATA, 0xF); } } void CANFrame_Rx_ISR(void) { if(pRxMsg2->rx_ff == CAN_FF_STANDARD) { stCAN_ReceiveFrame_Buf_Rx[stCANFrame_InfoRx.ucFrameWrInde].id = pRxMsg2->rx_sfid; } else if(pRxMsg2->rx_ff == CAN_FF_EXTENDED) { stCAN_ReceiveFrame_Buf_Rx[stCANFrame_InfoRx.ucFrameWrInde].id = pRxMsg2->rx_efid; } stCAN_ReceiveFrame_Buf_Rx[stCANFrame_InfoRx.ucFrameWrInde].rx_ff = (UBYTE)pRxMsg2->rx_ff; stCAN_ReceiveFrame_Buf_Rx[stCANFrame_InfoRx.ucFrameWrInde].rx_ft = (UBYTE)pRxMsg2->rx_ft; stCAN_ReceiveFrame_Buf_Rx[stCANFrame_InfoRx.ucFrameWrInde].rx_dlen = (UBYTE)pRxMsg2->rx_dlen; memcpy(stCAN_ReceiveFrame_Buf_Rx[stCANFrame_InfoRx.ucFrameWrInde].rx_data, (uint8_t*)pRxMsg2->rx_data, pRxMsg2->rx_dlen); stCANFrame_InfoRx.ucFrameWrInde++; if (stCANFrame_InfoRx.ucFrameWrInde >= stCANFrame_InfoRx.ucFrameSize) { stCANFrame_InfoRx.ucFrameWrInde = 0; } stCANFrame_InfoRx.ucFrameCnt++; if (stCANFrame_InfoRx.ucFrameCnt >= stCANFrame_InfoRx.ucFrameSize) { stCANFrame_InfoRx.ucFrameCnt = stCANFrame_InfoRx.ucFrameSize; } } void giant_CANRxData_Process(void) { CAN_ReceiveFrame_Struct_t *CAN_ReceiveFrame_tmp; if(stCANFrame_InfoRx.ucFrameCnt > 0) { CAN_ReceiveFrame_tmp = &stCAN_ReceiveFrame_Buf_Rx[stCANFrame_InfoRx.ucFrameRdInde]; if(CAN_ReceiveFrame_tmp->rx_ff == CAN_FF_EXTENDED) { stGiantStandardDataFrameID_rx.FunctionGroup = (UBYTE)((CAN_ReceiveFrame_tmp->id & 0x38000)>>15); stGiantStandardDataFrameID_rx.NodeGroup = (UBYTE)((CAN_ReceiveFrame_tmp->id & 0x07E00)>>9); stGiantStandardDataFrameID_rx.DataBehaviors = (UBYTE)((CAN_ReceiveFrame_tmp->id & 0x001C0)>>6); stGiantStandardDataFrameID_rx.DataAddress = (UBYTE)(CAN_ReceiveFrame_tmp->id & 0x0003F); if((stGiantStandardDataFrameID_rx.NodeGroup == NODE_SERVICETOOL)|| (stGiantStandardDataFrameID_rx.NodeGroup == NODE_USERINTERFACE))//上位机更新或者蓝牙通过仪表更新 { if((stGiantStandardDataFrameID_rx.DataAddress == 0x1) && (CAN_ReceiveFrame_tmp->rx_dlen == 6)) { UWORD Filemain_dir = ((CAN_ReceiveFrame_tmp->rx_data[1]) + (CAN_ReceiveFrame_tmp->rx_data[2]<<8)); UWORD Filesub_dir = ((CAN_ReceiveFrame_tmp->rx_data[3]) + (CAN_ReceiveFrame_tmp->rx_data[4]<<8)); if(((CAN_ReceiveFrame_tmp->rx_data[0] & 0x3F) == NODE_DRIVECHAIN) && (Filemain_dir == MC_FILEMAINDIR) && (Filesub_dir == MC_FILESUBDIR)) { if((CAN_ReceiveFrame_tmp->rx_data[5] & 0x0F) == 0x01) { UBYTE reply_data[6]; memcpy(reply_data, CAN_ReceiveFrame_tmp->rx_data, CAN_ReceiveFrame_tmp->rx_dlen); reply_data[0] = (0x40 | stGiantStandardDataFrameID_rx.NodeGroup); reply_data[5] = 0x10; giant_SendExtendData(0x01, DB_ACTIVEDATA, reply_data, CAN_ReceiveFrame_tmp->rx_dlen); UWORD app_data[4] = {0xAAAA, 0x5555, 0xBBBB, 0x6666};//标记为有app+下载中.. FLASH_voWriteMoreData(APPLICATIONSTATUS_ADDRESS, app_data, 4);//写入数据,boot判断0x5555AAAA决定跳转app的时间,判断0x6666BBBB决定是否发送MOTINOVA-boot power_stPowStateOut.powerstate = POWER_RESET; power_stPowStateOut.blPowerStartupFlg = FALSE; } } } } } else if(CAN_ReceiveFrame_tmp->rx_ft == CAN_FT_DATA)//Standard { stGiantStandardDataFrameID_rx.FunctionGroup = (UBYTE)((CAN_ReceiveFrame_tmp->id & 0x600)>>9); stGiantStandardDataFrameID_rx.NodeGroup = (UBYTE)((CAN_ReceiveFrame_tmp->id & 0x1E0)>>5); stGiantStandardDataFrameID_rx.DataBehaviors = (UBYTE)((CAN_ReceiveFrame_tmp->id & 0x010)>>4); stGiantStandardDataFrameID_rx.DataAddress = (UBYTE)(CAN_ReceiveFrame_tmp->id & 0x00F); switch (stGiantStandardDataFrameID_rx.NodeGroup) { case NODE_SERVICETOOL: { break; } case NODE_USERINTERFACE: { ulOBC_ComTimeOutCount = cp_ulSystickCnt; stGiantControlParams.RefreshFlag = TRUE; switch(stGiantStandardDataFrameID_rx.DataAddress) { case 0x0: { if(CAN_ReceiveFrame_tmp->rx_dlen == 2)//error { stGiantControlParams.Error = (CAN_ReceiveFrame_tmp->rx_data[0] & 0x01);//Error value } break; } case 0x1: { if(CAN_ReceiveFrame_tmp->rx_dlen == 7)//cmd1 { stGiantControlParams.ManualSleepEn = ((CAN_ReceiveFrame_tmp->rx_data[0] & 0x40)>>6);//Manual sleep stGiantControlParams.AutomaticSleepEn = ((CAN_ReceiveFrame_tmp->rx_data[0] & 0x20)>>5);//Automatic sleep stGiantControlParams.InactivateErrorDetection = ((CAN_ReceiveFrame_tmp->rx_data[1] & 0x80)>>7);//Inactivate the error detection if((CAN_ReceiveFrame_tmp->rx_data[1] & 0x10) == 0x10)//Reset fault history { } stGiantControlParams.ThrottleEn = ((CAN_ReceiveFrame_tmp->rx_data[1] & 0x08)>>3);//Throttle state if((CAN_ReceiveFrame_tmp->rx_data[1] & 0x04) == 0x04)//Reset trip distance and trip time { MC_RideLog.TRIP_Km = 0; MC_RideLog.TRIP_Time = 0; MC_RunInfo.Ride_Km = 0; MC_RunInfo.Ride_Time = 0; cp_stHistoryPara.ulTripSum = 0; cp_stHistoryPara.ulTripSumTime = 0; cp_stHistoryPara.ulODOTime = cp_stHistoryPara.ulODOTime + (cp_stBikeRunInfoPara.ulRiTime >> 10) / 60; cp_stBikeRunInfoPara.ulRiTime = 0; } stGiantControlParams.BrakeleEn = ((CAN_ReceiveFrame_tmp->rx_data[1] & 0x02)>>1);//Brake state stGiantControlParams.WalkEn = (CAN_ReceiveFrame_tmp->rx_data[1] & 0x01);//Walk if(CAN_ReceiveFrame_tmp->rx_data[2] > 100) { stGiantControlParams.ThrottlePowerPercentage = 0; } else { stGiantControlParams.ThrottlePowerPercentage = CAN_ReceiveFrame_tmp->rx_data[2];//Throttle power percentage %,else 0% } stGiantControlParams.RidingModeEn = ((CAN_ReceiveFrame_tmp->rx_data[3] & 0x80)>>7);//Riding mode stGiantControlParams.AdjustingMode = (CAN_ReceiveFrame_tmp->rx_data[3] & 0x1F);//Adjusting mode if((CAN_ReceiveFrame_tmp->rx_data[4] & 0x04) == 0x04)//Reset odometer distance and odometer time { MC_RideLog.ODO_Km = 0; MC_RideLog.ODO_Time = 0; cp_stHistoryPara.ulODOTrip = 0; cp_stHistoryPara.ulODOTime = 0; // cp_stHistoryPara.ulTripSum = 0; // cp_stHistoryPara.ulTripSumTime = 0; MC_UpcInfo.stHistoryInfo.uwODOTripH = 0; MC_UpcInfo.stHistoryInfo.uwODOTripL = 0; MC_UpcInfo.stHistoryInfo.uwODOTimeH = 0; MC_UpcInfo.stHistoryInfo.uwODOTimeL = 0; // MC_UpcInfo.stHistoryInfo.uwTripSumH = 0; // MC_UpcInfo.stHistoryInfo.uwTripSumL = 0; // MC_UpcInfo.stHistoryInfo.uwTripSumTimeH = 0; // MC_UpcInfo.stHistoryInfo.uwTripSumTimeL = 0; cp_stBikeRunInfoPara.ulRiTime = 0; } stGiantControlParams.StartMode = ((CAN_ReceiveFrame_tmp->rx_data[6] & 0xC0) >> 6);//Start mode,1-soft,2-normal,3-strong } break; } case 0x2: { if(CAN_ReceiveFrame_tmp->rx_dlen == 7)//cmd2 { if((CAN_ReceiveFrame_tmp->rx_data[0] & 0x30) == 0x00) { MC_ControlCode.LightSwitch = MC_LightSwitch_OFF;//light off } else if((CAN_ReceiveFrame_tmp->rx_data[0] & 0x30) == 0x10) { MC_ControlCode.LightSwitch = MC_LightSwitch_ON;//light on } else { //rsv } MC_RunInfo.LightSwitch = MC_ControlCode.LightSwitch; stGiantControlParams.WheelCircumference = (CAN_ReceiveFrame_tmp->rx_data[2] + (CAN_ReceiveFrame_tmp->rx_data[3]<<8));//Tire circumference,900-2500mm stGiantControlParams.MaximumTorque = ((CAN_ReceiveFrame_tmp->rx_data[4] & 0xF0)>>4);//Maximum torque,*10Nm // if(0 == stGiantControlParams.MaximumTorque) // { // stGiantControlParams.MaximumTorque = 0;//default // } stGiantControlParams.Acceleration = (CAN_ReceiveFrame_tmp->rx_data[4] & 0x0F);//Acceleration,*30Nm/s // if(0 == stGiantControlParams.Acceleration) // { // stGiantControlParams.Acceleration = 0;//default // } stGiantControlParams.AssistRatio = CAN_ReceiveFrame_tmp->rx_data[5];;//Assist ratio, *10% stGiantControlParams.MaximumPower = CAN_ReceiveFrame_tmp->rx_data[6];//Maximum power, *10Watt } break; } case 0x3: { if(CAN_ReceiveFrame_tmp->rx_dlen == 7)//cmd3 { stGiantControlParams.SpeedLimitation = (UWORD)(CAN_ReceiveFrame_tmp->rx_data[5] + (CAN_ReceiveFrame_tmp->rx_data[6]<<8));//speed limitation,0.01km/h // if(0 == stGiantControlParams.SpeedLimitation) // { // stGiantControlParams.SpeedLimitation = 2500;//DU default // } } break; } default: break; } break; } case NODE_MOTINOVA: { break; } case NODE_ENERGYPACK: { ulBMS_ComTimeOutCount = cp_ulSystickCnt; switch(stGiantStandardDataFrameID_rx.DataAddress) { case 0x1: { if(CAN_ReceiveFrame_tmp->rx_dlen == 8)//Capacity { BMS_RunInfo.SOC = CAN_ReceiveFrame_tmp->rx_data[0]; } break; } default: break; } break; } case NODE_GIANTAPP: { switch(stGiantStandardDataFrameID_rx.DataAddress) { case 0x4: { if(CAN_ReceiveFrame_tmp->rx_dlen == 8)//Customized Version { memcpy(MC_RsASSCII.CustomASCII1, CAN_ReceiveFrame_tmp->rx_data, 8); //执行存储操作 memcpy(flash_stPara.ubRsASSCII.CustomASCII1, MC_RsASSCII.CustomASCII1, sizeof(MC_RsASSCII.CustomASCII1)); } break; } default: break; } break; } default: break; } } else if(CAN_ReceiveFrame_tmp->rx_ft == CAN_FT_REMOTE)//Standard { stGiantStandardRemoteFrameID_rx.MotionGroup = (UBYTE)((CAN_ReceiveFrame_tmp->id & 0x700)>>8); stGiantStandardRemoteFrameID_rx.RequireNodeGroup = (UBYTE)((CAN_ReceiveFrame_tmp->id & 0x0F0)>>4); stGiantStandardRemoteFrameID_rx.ResponseNodeGroup = (UBYTE)(CAN_ReceiveFrame_tmp->id & 0x00F); if(stGiantStandardRemoteFrameID_rx.RequireNodeGroup == NODE_USERINTERFACE) { ulOBC_ComTimeOutCount = cp_ulSystickCnt; } if((stGiantStandardRemoteFrameID_rx.ResponseNodeGroup == NODE_ALL) || (stGiantStandardRemoteFrameID_rx.ResponseNodeGroup == NODE_DRIVECHAIN))// { switch(stGiantStandardRemoteFrameID_rx.MotionGroup) { case MG_HEARTBEAT: { giant_SendDriveChainPassiveData(stGiantStandardRemoteFrameID_rx.MotionGroup,0xF); break; } case MG_CONFIRMATION: { giant_SendDriveChainPassiveData(stGiantStandardRemoteFrameID_rx.MotionGroup,0xF); break; } case MG_ACTIVEDATA1: { for(int i=0;i<5;i++) { giant_SendDriveChainActiveData(FG_RESPONSEDATA, i); } for(int j=6;j<8;j++) { giant_SendDriveChainActiveData(FG_RESPONSEDATA, j); } break; } case MG_ACTIVEDATA2: { giant_SendDriveChainActiveData(FG_RESPONSEDATA, 0x8); giant_SendDriveChainActiveData(FG_RESPONSEDATA, 0xF); break; } case MG_PASSIVEDATA1: { giant_SendDriveChainPassiveData(stGiantStandardRemoteFrameID_rx.MotionGroup,0x0); giant_SendDriveChainPassiveData(stGiantStandardRemoteFrameID_rx.MotionGroup,0x1); giant_SendDriveChainPassiveData(stGiantStandardRemoteFrameID_rx.MotionGroup,0x2); break; } case MG_PASSIVEDATA2: { giant_SendDriveChainPassiveData(stGiantStandardRemoteFrameID_rx.MotionGroup,0x3); giant_SendDriveChainPassiveData(stGiantStandardRemoteFrameID_rx.MotionGroup,0x4); giant_SendDriveChainPassiveData(stGiantStandardRemoteFrameID_rx.MotionGroup,0x5); break; } case MG_PASSIVEDATA3: { break; } case MG_PASSIVEDATA4: { giant_SendDriveChainPassiveData(stGiantStandardRemoteFrameID_rx.MotionGroup,0xB); giant_SendDriveChainPassiveData(stGiantStandardRemoteFrameID_rx.MotionGroup,0xC); break; } default: break; } } } giant_DataProcess(); stCANFrame_InfoRx.ucFrameCnt--; stCANFrame_InfoRx.ucFrameRdInde++; if (stCANFrame_InfoRx.ucFrameRdInde >= stCANFrame_InfoRx.ucFrameSize) { stCANFrame_InfoRx.ucFrameRdInde = 0; } } } void giant_SendDriveChainPassiveData(UBYTE remoteMG, UBYTE DataAddr) { UBYTE len = 8; UBYTE data[8] = {0,}; UWORD ID = 0; ID = ((FG_RESPONSEDATA<<9) |(NODE_DRIVECHAIN<<5) |(DB_PASSIVEDATA<<4) |DataAddr); switch(DataAddr) { case 0x0: { memcpy(data, (UBYTE *)"MOAACITY", 8);//Mode name break; } case 0x1: { memcpy(data, MC_VerInfo.FW_Version, 8);//FW1 break; } case 0x2: { memcpy(data, &MC_VerInfo.FW_Version[8], 8);//FW2 break; } case 0x3: { memcpy(data, MC_VerInfo.HW_Version, 8);//HW1 break; } case 0x4: { memcpy(data, &MC_VerInfo.HW_Version[8], 8);//HW2 break; } case 0x5: { memcpy(data, MC_RsASSCII.CustomASCII1, 8);//Customized Version break; } case 0xB: { memcpy(data, MC_VerInfo.ProductLabel, 8);//SN1 break; } case 0xC: { memcpy(data, &MC_VerInfo.ProductLabel[8], 8);//SN2 break; } case 0xF: { len = 4; data[0] = 0x1;//success memcpy(&data[1], &stGiantControlParams.WheelCircumference, 2);//circumference data[3] = (UBYTE)ass_stParaCong.swDeltPerimeter; break; } default: break; } CAN_SendData(ID, data, len); } void giant_SendDriveChainActiveData(UBYTE functiongroup, UBYTE dataaddr) { UBYTE len = 8; UBYTE data[8] = {0,}; UWORD ID = 0; ID = ((functiongroup<<9) |(NODE_DRIVECHAIN<<5) |(DB_ACTIVEDATA<<4) |dataaddr); switch(dataaddr) { case 0x0: //Error { len = 2; if(MC_ErrorCode.Code > 0) { data[0] |= 0x01;// Corresponding error occurs } else { data[0] &= 0xFE;// Corresponding error was gone } data[1] = 0x60;//Error code-Normal break; } case 0x1: //Cycling State { len = 5; if(stGiantControlParams.CommSleep >= 1) { data[0] |= 0x01;//Communication sleep } if(MC_RunInfo.LightSwitch == MC_LightSwitch_ON) { data[2] |= (0x01<<6); } data[2] |= (stGiantControlParams.StartMode<<4); data[2] |= (MC_RunInfo.CadenceDir<<2); data[3] = (UBYTE)(stGiantControlParams.SpeedLimitation & 0xFF);// speed limitation,0.01km/h data[4] = (UBYTE)((stGiantControlParams.SpeedLimitation & 0xFF00) >> 8); break; } case 0x2: //Cycling data { len = 8; data[0] = (UBYTE)(MC_RunInfo.BikeSpeed & 0xFF);// bike speed,0.1km/h data[1] = (UBYTE)((MC_RunInfo.BikeSpeed & 0xFF00) >> 8); data[2] = (UBYTE)((MC_RunInfo.Torque*10) & 0xFF);// pedal torque,0.1Nm data[3] = (UBYTE)(((MC_RunInfo.Torque*10) & 0xFF00) >> 8); data[4] = (UBYTE)((MC_RunInfo.Cadence*10) & 0xFF);// cadence,0.1RPM data[5] = (UBYTE)(((MC_RunInfo.Cadence*10) & 0xFF00) >> 8); data[6] = (UBYTE)((MC_RunInfo.BusCurrent/10) & 0xFF);// phase current,0.01A data[7] = (UBYTE)(((MC_RunInfo.BusCurrent/10) & 0xFF00) >> 8); break; } case 0x3: //cycling data 1 { len = 8; if(blBMSCommFault == TRUE) { data[1] = MC_RunInfo.SOC;//% } else { data[1] = 0xFF; } data[2] = (UBYTE)(MC_RideLog.TRIP_Km & 0xFF);// trip distance,0.1km data[3] = (UBYTE)((MC_RideLog.TRIP_Km & 0xFF00) >> 8); data[4] = (UBYTE)(MC_RideLog.TRIP_Time & 0xFF);// trip time,min data[5] = (UBYTE)((MC_RideLog.TRIP_Time & 0xFF00) >> 8); data[6] = (UBYTE)((MC_RideLog.ODO_Km /10) & 0xFF);// odometer distance,km data[7] = (UBYTE)(((MC_RideLog.ODO_Km /10) & 0xFF00) >> 8); break; } case 0x4: { len = 8; data[0] = (UBYTE)((MC_RideLog.ODO_Time/60) & 0xFF);// odometer time,h data[1] = (UBYTE)(((MC_RideLog.ODO_Time/60) & 0xFF00) >> 8); if(adc_stUpOut.PCBTemp>254) { data[2] = 127; data[5] = 127; } else if(adc_stUpOut.PCBTemp>127) { data[2] = 127; data[5] = (UBYTE)(adc_stUpOut.PCBTemp/2); } else { data[2] = (UBYTE)adc_stUpOut.PCBTemp; data[5] = (UBYTE)(adc_stUpOut.PCBTemp/2); } break; } case 0x6: { len = 8; data[0] = (UBYTE)(MC_RunInfo.BusVoltage & 0xFF);// bus input voltage,mV data[1] = (UBYTE)((MC_RunInfo.BusVoltage & 0xFF00) >> 8); data[2] = (UBYTE)((BMS_VoltEstimat.uwIbusLpf/10) & 0xFF);//bus input current,0.01A data[3] = (UBYTE)(((BMS_VoltEstimat.uwIbusLpf/10) & 0xFF00) >> 8); data[4] = (UBYTE)(MC_RunInfo.MotorSpeed & 0xFF);// motor rotor speed,RPM data[5] = (UBYTE)((MC_RunInfo.MotorSpeed & 0xFF00) >> 8); // data[6] = (UBYTE)(MC_RunInfo.RemainDistance & 0xFF);// remaining range of drive chain system,km // data[7] = (UBYTE)((MC_RunInfo.RemainDistance & 0xFF00) >> 8); break; } case 0x7: { len = 8; data[0] = (UBYTE)(MC_RunInfo.Ride_Km & 0xFF);// ride distance after power on,0.1km data[1] = (UBYTE)((MC_RunInfo.Ride_Km & 0xFF00) >> 8); data[2] = (UBYTE)((MC_RunInfo.Ride_Time/60) & 0xFF);//ride time after power on,min data[3] = (UBYTE)(((MC_RunInfo.Ride_Time/60) & 0xFF00) >> 8); data[4] = (UBYTE)((cp_stHistoryPara.ulRealODOTrip/10) & 0xFF);// total ride distance Can’t be reset data[5] = (UBYTE)(((cp_stHistoryPara.ulRealODOTrip/10) & 0xFF00) >> 8); data[6] = (UBYTE)((cp_stHistoryPara.ulRealODOTime/60) & 0xFF);// rtotal ride time Can’t be reset data[7] = (UBYTE)(((cp_stHistoryPara.ulRealODOTime/60) & 0xFF00) >> 8); break; } case 0x8: { len = 5; data[0] = stGiantControlParams.AssistRatio;// Assist ratio state data[1] = stGiantControlParams.MaximumPower;//Maximum power data[2] = (stGiantControlParams.MaximumTorque<<4)|(stGiantControlParams.Acceleration);// rtotal ride time Can’t be reset if(adc_stUpOut.PCBTemp>254) { data[3] = 127; } else { data[3] = (UBYTE)(adc_stUpOut.PCBTemp/2); } data[4] = MC_RunInfo.PowerPerKm;//Average power consumption ,0.01Ah/km break; } case 0xF: { len = 6; // data[4] = (UBYTE)(MC_RunInfo.RemainDistance & 0xFF);// human power // data[5] = (UBYTE)((MC_RunInfo.RemainDistance & 0xFF00) >> 8); break; } default: break; } CAN_SendData(ID, data, len); } void giant_SendRemote(UBYTE motiongroup) { UWORD ID = 0; ID = ((motiongroup<<8) |(NODE_DRIVECHAIN<<4) |NODE_USERINTERFACE); CAN_SendRemote(ID); } void giant_SendExtendData(UBYTE dataaddr, UBYTE datatype, UBYTE *data, UBYTE len) { ULONG ID = 0; can_trasnmit_message_struct can_trasnmit_message1; ULONG OVtim = 0; ID = 0x1FFC0000 + (FG_NORMALDATA<<15) + (NODE_DRIVECHAIN<<9) + (datatype<<6) + dataaddr; can_trasnmit_message1.tx_efid = ID; can_trasnmit_message1.tx_ff = CAN_FF_EXTENDED; can_trasnmit_message1.tx_ft = CAN_FT_DATA; can_trasnmit_message1.tx_dlen = len; memcpy(can_trasnmit_message1.tx_data, data, len); can_ubMbox = can_message_transmit(CAN0, &can_trasnmit_message1); while((can_transmit_states(CAN0,can_ubMbox) != CAN_TRANSMIT_OK) && (OVtim < 0XFFF)) { OVtim++; } if (OVtim >= 0XFFF) { return; } } void giant_DataProcess(void) { if(stGiantControlParams.RefreshFlag) { stGiantControlParams.RefreshFlag = FALSE; ass_stParaCong.uwStartMode = stGiantControlParams.StartMode; if(MC_WorkMode != 1) { if((stGiantControlParams.AdjustingMode >= AD_CHECKMODE) && (stGiantControlParams.AdjustingMode <= AD_OFFMODE)) { MC_ControlCode.GearSt = MC_GearSt_OFF; } else if(stGiantControlParams.WalkEn == 1) { MC_ControlCode.GearSt = MC_GearSt_WALK; } else if((stGiantControlParams.AdjustingMode >= AD_SERVICEMODE_S) && (stGiantControlParams.AdjustingMode <= AD_SERVICEMODE_E)) { MC_ControlCode.GearSt = MC_GearSt_OFF; } else if(stGiantControlParams.RidingModeEn == 0) { MC_ControlCode.GearSt = MC_GearSt_OFF; } else if(stGiantControlParams.AssistRatio == 0) { MC_ControlCode.GearSt = MC_GearSt_OFF; } else { MC_ControlCode.GearSt = MC_GearSt_Torque_ECO; } MC_RunInfo.GearSt = (UBYTE)MC_ControlCode.GearSt; } if(stGiantControlParams.AdjustingMode == AD_CHECKMODE) { //轮径更新 UWORD tmpdata; if(stGiantControlParams.WheelCircumference < 900) { tmpdata = 90;//default } else if(stGiantControlParams.WheelCircumference > 2500) { tmpdata = 250;//default } else { tmpdata = stGiantControlParams.WheelCircumference/10; } if((stGiantControlParams.AdjustingMode == AD_CHECKMODE) && (MC_UpcInfo.stBikeInfo.uwWheelPerimeter != tmpdata)) { MC_UpcInfo.stBikeInfo.uwWheelPerimeter = tmpdata; MC_UpcInfo.stBikeInfo.uwSaveFlg = 0; cp_stFlg.ParaSaveEEFlg = FALSE; cp_stFlg.ParaUpdateFlg = TRUE; cp_stFlg.ParaBikeInfoUpdateFlg = TRUE; cp_stFlg.ParaAssistUpdateFinishFlg = TRUE; } } //限速更新 if(MC_UpcInfo.stAssistInfo.uwAssistLimitBikeSpdStart != (stGiantControlParams.SpeedLimitation/100)) { MC_UpcInfo.stAssistInfo.uwAssistLimitBikeSpdStart = stGiantControlParams.SpeedLimitation/100; MC_UpcInfo.stAssistInfo.uwAssistLimitBikeSpdStop = stGiantControlParams.SpeedLimitation/100 + 2; MC_UpcInfo.stBikeInfo.uwThrottleMaxSpdKmH = stGiantControlParams.SpeedLimitation/100; MC_UpcInfo.stBikeInfo.uwSaveFlg = 0; MC_UpcInfo.stAssistInfo.uwSaveFlg = 0; cp_stFlg.ParaSaveEEFlg = FALSE; cp_stFlg.ParaUpdateFlg = TRUE; cp_stFlg.ParaAInfoUpdateFlg = TRUE; cp_stFlg.ParaBikeInfoUpdateFlg = TRUE; cp_stFlg.ParaAssistUpdateFinishFlg = TRUE; } } } SLONG giant_slPolynomial(const SWORD *value) { SLONG out; UWORD gain; if(stGiantControlParams.StartMode == 1) { gain = 82; } else if(stGiantControlParams.StartMode == 3) { gain = 123; } else { gain = 102; } if(MC_WorkMode == 1) { gain = 102; stGiantControlParams.AssistRatio = 35; } out = stGiantControlParams.AssistRatio * *value * gain >> 10; return out; } /************************************************************************* End of this File (EOF)! Do not put anything after this part! *************************************************************************/